Reputation: 45
why type c inferred the ture ? I think it is wrong. But how does it work? Why got a different result from the Equal?
type s1<X> = <T>() => T extends X ? 1 : '2'
type k1 = s1<'s1'> //type k1 = <T>() => T extends "s1" ? 1 : "2"
type k2 = s1<'s2'> //type k2 = <T>() => T extends "s2" ? 1 : "2"
type c = k1 extends k2 ? true : false // type c = true
type Equal<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false
type d = Equal<'s1', 's2'> // false
Upvotes: 0
Views: 80
Reputation: 26344
extends
tests if the left operand is a more specific subset of the right operand.
For example, "foo" | "bar" extends string
is true, because "foo" | "bar"
is more specific than string
. It's a subset of the type string
.
Likewise, string extends "foo" | "bar"
is false.
It's easy to think about like this (pretend this is valid):
const variable: string = "foo" | "bar";
This is valid; "foo" or "bar" can be assigned to string
.
However, this isn't:
const variable: "foo" | "bar" = string;
The string could be any string other than "foo" or "bar"!
Now I think where you're confused is that in this type:
type s1<X> = <T>() => T extends X ? 1 : '2'
It isn't:
type s1<X> = (<T>() => T) extends X ? 1 : '2'
But rather:
type s1<X> = <T>() => (T extends X ? 1 : '2')
You're passing strings to s1
, so the resulting types are `() => (T extends 's1' ? 1 : "2").
I believe TypeScript perceives them as the same because they both have the same signature: <T>() => string | number
.
This gives you true
, the expected outcome.
Upvotes: 1