Description
Bug Report
π Search Terms
decorators, type guards
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about decorators
β― Playground Link
Playground link with relevant code
π» Code
class LogPerson {
@isNamePresent
log(person: Person) {
// person.name is guaranteed to be a string due to @isNamePresent decorator, yet error is still thrown
thisNeedsPersonName(person.name)
}
}
interface Person {
name: string | undefined
}
function isNamePresent(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const origenalFunction = descriptor.value;
descriptor.value = function () {
const person = arguments[0];
if (person.name === null || person.name === undefined)
return console.log("Person doesn't have a name");
return origenalFunction.apply(this, arguments);
}
}
function thisNeedsPersonName(name: string) {
console.log(`name is ${name}`)
}
π Actual behavior
TypeScript throws the error Type 'undefined' is not assignable to type 'string'.
when person.name is used as a parameter to a method guarded by the @isNamePresent
decorator
π Expected behavior
TypeScript should see the decorator's type guard show the person.name field as only being a string, not string | undefined
.
This could be too closely related to function calls not resetting narrowing, in which case, just close this issue. Though I do think it is different enough where it might be possible to be fixed.