Skip to content

Can't infer param type of method assigned to computed property name using string enum value #20856

Closed
@UselessPickles

Description

@UselessPickles

TypeScript Version: 2.6.2

Code
With all strict options enabled...

// visitor interface for visiting possible values of a string literal type
type StringVisitor<S extends string, R> = {
    [P in S]: (value: P) => R;
};

enum Direction {
    LTR = "ltr",
    RTL = "rtl"
}

// "identity" visitor that just returns the visited value
const visitor: StringVisitor<Direction, Direction> = {
    // ERROR: Parameter 'value' implicitly has type 'any'.
    [Direction.LTR]: (value) => {
        return value
    },
    
    // no error - type of param properly inferred a type Direction.RTL
    ["rtl"]: (value) => {
        return value;
    }
}

Expected behavior:

No compiler error. The type of the param of the [Direction.LTR] method should be inferred as type Direction.LTR.

Actual behavior:
Compiler error because the type of the param of the [Direction.LTR] method is not inferred, so it is implicitly any.

It is interesting to me that I can use the enum values as computed property names to fulfill the requirements of the StringVisitor<Direction, Direction> type if I DON'T use parameters:

// No errors
const visitor: StringVisitor<Direction, Direction> = {
    [Direction.LTR]: () => {
        return Direction.LTR;
    },
    
    // no error
    [Direction.RTL]: () => {
        return Direction.RTL;
    }
}

Or if I explicitly provide the param type, everything lines up and compiles just fine:

// No errors
const visitor: StringVisitor<Direction, Direction> = {
    [Direction.LTR]: (value: Direction.LTR) => {
        return value;
    },
    
    [Direction.RTL]: (value: Direction.RTL) => {
        return value;
    }
}

The [Direction.LTR] and [Direction.RTL] property names seem to be understood as compile-time string literals for the purpose of matching up against the properties of the StringVisitor<Direction, Direction> type, and the distinct signatures of each property is known by the compiler for the purpose of checking that I provide a function of the correct type... so why can't the compiler infer the type of the param if I omit the param type?

NOTE: the same issue exists even if I declare the enum as a const enum.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions