Skip to content

Check inferred constraints for 'infer X' type variables #22323

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

Merged
merged 4 commits into from
Mar 5, 2018

Conversation

ahejlsberg
Copy link
Member

With this PR we properly check inferred constrains for infer X type variables in conditional types. Specifically, during type inference in a conditional type, when a candidate type for an infer X type variable doesn't satisfy the constraint inferred for that type variable (see #21709), the candidate is replaced with the constraint. That will subsequently cause the conditional check to be false. For example:

type MustBeString<T extends string> = T;
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;

type T1 = EnsureIsString<"hello">;  // "hello"
type T2 = EnsureIsString<42>;  // never

Previously, T2 would be the type 42 which doesn't satisfy the constraint string inferred from MustBeString.

Fixes #22221.

@ahejlsberg ahejlsberg requested a review from mhegazy March 5, 2018 14:35
@ahejlsberg ahejlsberg merged commit 1192a18 into master Mar 5, 2018
@ahejlsberg ahejlsberg deleted the checkInferredConstraints branch March 5, 2018 18:18
@zpdDG4gta8XKpMCd
Copy link

zpdDG4gta8XKpMCd commented Mar 6, 2018

@ahejlsberg is there a way to express Not?

type Not<T, U> = ... // T can be anything but U, if T is U then error
// use case:
function notSupposedToTakeAsyncCallbacks<X>(callback: () => Not<X, Promise<any>>) {
}

@mhegazy
Copy link
Contributor

mhegazy commented Mar 6, 2018

there is not really a way to throw an error. so the best that is possible today is to return a type that will cause a down-stream error, something like never would be good.
So you can define Not as:

type Not<T, U> = T extends U ? never : T;

type t1 = Not<{ a: number }, Promise<any>>; // { a: number } 

type t2 = Not<Promise<number>, Promise<any>>; // never

@zpdDG4gta8XKpMCd
Copy link

another silly questions please

#22375 (comment)

@microsoft microsoft locked and limited conversation to collaborators Jul 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants