Skip to content

Runtime type-checking fails for other values of same type #33548

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

Closed
Pentadome opened this issue Sep 23, 2019 · 4 comments
Closed

Runtime type-checking fails for other values of same type #33548

Pentadome opened this issue Sep 23, 2019 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@Pentadome
Copy link

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.

@jack-williams
Copy link
Collaborator

The type T could be wider than just string, so there is no guarantee that all values are strings.

transform(['a string', true, false], "")

You would need something like #28430 for this to be correct.

@Pentadome
Copy link
Author

Pentadome commented 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
Copy link
Collaborator

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.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Sep 23, 2019
@typescript-bot
Copy link
Collaborator

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants