Closed
Description
typescript@next ~ vscode plugin
Runtime type-checking fails for other values of same type
Code
transform<T>(items: T[], orderKey: string, reverse?: boolean): T[] {
items.sort((a, b) => {
const firstVal = findNested<T>(reverse ? b : a, orderKey);
//findNested returns T
if (firstVal == null) return 0;
const secondVal = findNested<T>(reverse ? a : b, orderKey);
if (typeof firstVal === "string") {
return this.stringCompare(firstVal, secondVal);
// ERROR, compiler doesn't know if secondVal is string
}
}
Expected behavior:
Compiler knows both values are T and therefor after typechecking one value, the other value is of the same expected type as the checked value.
Actual behavior:
Even though both values are of type T, not both values are of the same type anymore after type check.
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
jack-williams commentedon Sep 23, 2019
The type
T
could be wider than juststring
, so there is no guarantee that all values are strings.You would need something like #28430 for this to be correct.
Pentadome commentedon Sep 23, 2019
But if the array is T[], and one of the T's is a string for sure, shouldn't the compiler assume every T is a string?
jack-williams commentedon Sep 23, 2019
No, as my example shows this assumption is not valid. Subtyping lets you widen the type of a container so that it could contain values that do not behave uniformly under
typeof
, or some other predicate.While I expect that in most cases the intent would be for every value to be a string, it's not true in general and it would be incorrect to behave as if it were. Unfortunately, TypeScript currently has no facility to take that intent and allow a user to explicitly indicate it in the type. That is part of my proposal in #28430.
typescript-bot commentedon Sep 25, 2019
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.