TonyUndefined
TonyUndefined

Reputation: 45

How should I understand the extends keyword in typeScript? Examples inside

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

Answers (1)

tenshi
tenshi

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

Related Questions