Description
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
.