Condition type of Ts series

insert image description here

Condition type of Ts series

foreword

This article mainly explains the usage of ts conditional type.

1. First encounter

1. First, let's take a look at a small example:

interface Person {
    
    
  name: string;
  age: number;
}
interface Son extends Person{
    
    
  hobby: string;
}
const son1: Son = {
    
    
  name: 'son1',
  age: 1,
  hobby: 'son2'
}

Analysis:

Two interfaces are defined here, namely Personand Son, and then defined son1to implement Sonthe interface

2. Make a small change, so now I want to return the specified type of things according to different types, how to do it
Example:

type Person = {
    
    
    name: string;
    age: number
}
type Car = boolean
type TestType<T> = T extends object ? Person : Car
type T1 = TestType<string>
const test: T1 =  true

Analysis:
Then define the two types of Person and Car here. First, judge whether the generic type T inherits the object type. If yes, then return the Person type. If not, then return the Car type. The string type in the example is of course not the object type, so the test variable test needs to be assigned a boolean type
.

2. Condition judgment

1. See the type expression above, is it similar to the ternary expression in js?
The chain judgment supported in js also supports this writing method in ts. It should be noted here that the writing method is not the same as the usage.
First look at the chain judgment in js:
const test = a ? b : c ? d : e
This is easy to understand: first judge whether a is true, if yes, return b, if not, return c, and so on, so I won’t go into details.
Then take a look at the chain judgment of ts:

type TypeName<T> = T extends string
    ? "string"
    : T extends number
        ? "number"
        : T extends boolean
            ? "boolean"
            : T extends undefined
                ? "undefined"
                : T extends Function
                    ? "function"
                    : "object"
type T0 = TypeName<string>; // "string"
type T1 = TypeName<"a">; // "string"
type T2 = TypeName<true>; // "boolean"
type T3 = TypeName<() => void>; // "function"
type T4 = TypeName<string[]>; // "object"

Analysis:
This means that when the incoming generic T can be assigned a value of string, number, boolean, undefined, or Function, different result types are returned.

2. Of course, if the generic type you pass in is a joint type, then the result returned to you will also be a joint type.
Because the following example:

type T10 = TypeName<string | (() => void)>; // "string" | "function"
type T12 = TypeName<string | string[] | undefined>; // "string" | "object" | "undefined"
type T11 = TypeName<string[] | number[]>; // "object"

The incoming union type will be expanded to the following example:

//T10:
string extends string
    ? "string"
    : T extends number
    ? "number"
    : T extends boolean
    ? "boolean"
    : T extends undefined
    ? "undefined"
    : T extends Function
    ? "function"
    : "object" | 
"function" extends string
    ? "string"
    : T extends number
    ? "number"
    : T extends boolean
    ? "boolean"
    : T extends undefined
    ? "undefined"
    : T extends Function
    ? "function"
    : "object"

So it is easy to understand why when the generic type T is passed in as a joint type, the returned type result will also be a joint type.

Three, to be supplemented

Guess you like

Origin blog.csdn.net/qq_43205326/article/details/131335299