Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Decorator Method Name Type Restriction By Enum #30667

Open
ozyman42 opened this issue Mar 30, 2019 · 1 comment
Open

bug: Decorator Method Name Type Restriction By Enum #30667

ozyman42 opened this issue Mar 30, 2019 · 1 comment
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@ozyman42
Copy link

ozyman42 commented Mar 30, 2019

TypeScript Version: 3.3.3

Search Terms:

is:issue decorator type method name propertyKey

Code:
this works as expected:

interface SomeTypeMap {
    fieldOne: string;
    fieldTwo: number;
}

function MethodDecorator<Key extends keyof SomeTypeMap>(
    target: SomeClass,
    methodName: Key,
    descriptor: TypedPopertyDescriptor<(...args: any[]) => SomeTypeMap[Key]>) {
    /* some implementation */
}

class SomeClass {
    // works fine, as expected
    @MethodDecorator
    public fieldOne() {
        return "";
    }

    // compiler error, as expected
    // since it returns string instead of number
    @MethodDecorator
    public fieldTwo() {
        return "";
    }

    // compiler error, as expected
    // since method name is not a key in SomeTypeMap
    @MethodDecorator
    public fieldThree() {
        return "";
    }
}

this does not work as expected:

enum Field {
    One = "fieldOne"
}

interface SomeTypeMap {
    [Field.One]: string;
}

function MethodDecorator<Key extends keyof SomeTypeMap>(
    target: SomeClass,
    methodName: Key,
    descriptor: TypedPopertyDescriptor<(...args: any[]) => SomeTypeMap[Key]>) {
    /* some implementation */
}

class SomeClass {
    // compiler error, unexpected
    @MethodDecorator
    public [Field.One]() {
        return "";
    }
}

Expected behavior:

In the second code example, I would expect there to be no compiler errors.

Actual behavior:

Error message: Argument of type 'string' is not assignable to parameter of type Field

The method name seems to be of type string here, which is true, but it should also be of type Field

Playground Link:

can't enable experimental decorators in the playground.

Related Issues:

#17795

less related:
#30102

Comments:

Thanks for all your hard work TypeScript team.

@ozyman42
Copy link
Author

ozyman42 commented Mar 31, 2019

As a workaround, I am using Symbols as such:

namespace Field {
    export const One = Symbol("something")
    export const Two = Symbol("another thing")
}

interface SomeTypeMap {
    [Field.One]: string;
    [Field.Two]: number;
}

function MethodDecorator<Key extends keyof SomeTypeMap>(
    target: SomeClass,
    methodName: Key,
    descriptor: TypedPopertyDescriptor<(...args: any[]) => SomeTypeMap[Key]>) {
    /* some implementation */
}

class SomeClass {
    // works fine, as expected
    @MethodDecorator
    public [Field.One]() {
        return "";
    }

    // compiler error, as expected
    // since it returns string instead of number
    @MethodDecorator
    public [Field.Two]() {
        return "";
    }
}

For some reason this works fine.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Apr 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

3 participants