Allow decorators to apply type guards to arguments of the method/function they decorate ยท Issue #50159 ยท microsoft/TypeScript (original) (raw)

Bug Report

๐Ÿ”Ž Search Terms

decorators, type guards

๐Ÿ•— Version & Regression Information

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 originalFunction = 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 originalFunction.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.