ts:条件类型

1. 条件类型表达式 T extends U ? X : Y

基本语法: T extends U ? X : Y

(T 和 U 是类型,而 X 和 Y 是类型或者类型表达式。)

用于判断 T的每个成员 是否是 U 的子类型。如果是,则返回 X,否则返回 Y。最终返回多个Y 联合的结果(never在联合类型中会被忽略)

c 复制代码
1. 基本用法--判断类型
// 判断是不是字符串
type IsString<T> = T extends string ? true : false;
type Result1 = IsString<string>;      // true  
//判断是不是数组
type isArray<T> = T extends Array<any> ? true : false
type testArray = isArray<'123'>
判断是不是对象
type isObject<T> T extends object > true : false
type testObject = isObject<{a:'123'}>
2. 提取元组的类型
type ArrayElementType<T extends any[]> = T extends (infer U)[] ? U : never;  
// 使用示例  
const numbers: number[] = [1, 2, 3];  
type NumberElementType = ArrayElementType<typeof numbers>; // number  
3. 排除null或undefined的类型
type noNull<T> = T extends null | undefined ? never : T
type Result1 = noNull<string | null>
4. 递归条件类型示例
type DeepArrayElementType<T> =  
  T extends any[]  
    ? T[number] extends infer U  
      ? U extends any[]  
        ? DeepArrayElementType<U>  
        : U  
      : never  
    : T;  
  
// 使用通用版本  
type Example5 = DeepArrayElementType<number[][][]>; // number  
type Example6 = DeepArrayElementType<string | number[][]>; // string | number
6. 条件烈类型与泛型类型结合使用

条件表达式可以实现递归

c 复制代码
// 只针对接口的递归
//实现一个泛型 DeepReadonly<T>,它将对象的每个参数及其子对象递归地设为只读。
type X = {
  x: {
    a: 1;
    b: "hi";
  };
  y: "hey";
};

type Expected = {
  readonly x: {
    readonly a: 1;
    readonly b: "hi";
  };
  readonly y: "hey";
};

type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};

let zs: DeepReadonly<X> = {
  x: {
    a: 1,
    b: "hi",
  },
  y: "hey",
};
zs.x.b = "xc";

infer

infer 关键字用于在泛型条件类型中推断类型。它允许你声明一个类型变量,该变量会在条件类型被解析时自动推断出具体的类型。
infer 关键字通常与条件类型和映射类型中的 extends 关键字一起使用,但是,infer 并不一定要与 extends 结合使用。
infer 可以在一个条件类型中多次使用,以捕获不同的类型信息。

c 复制代码
1. 提取数组元素类型
type ElementType<T extends any[]> = T extends (infer U)[] ? U : never;  
// 使用示例  
type NumArrayElementType = ElementType<[1, 2, 3, 4]>; // number  
type MixedArrayElementType = ElementType<[1, "two", true]>; // number | "two" | true,但通常这不是我们想要的
2. 提取数组最后一个元素类型
type arr1 = [1, 2, 3]
type FirstElement<T extends any[]> =  
  T extends [...infer First, infer Rest] ? Rest : never;  
type lastTest  = FirstElement<arr1>
3. 提取数组第一个元素类型
type arr2 = ['a', 'b', 'c']
type FirstElement<T extends any[]> =  
  T extends [infer First, ...infer Rest] ? First : never;  
type firstTest  = FirstElement<arr1>
4. 提取函数参数类型
type FunctionParams<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;  
type Params = FunctionParams<(a: string, b: number) => void>; 
5. 提取对象属性值类型
type ValueTypeOfProperty<T, K extends keyof T> = T[K] extends (infer V) ? V : never;  
type Obj = {  
  a: string;  
  b: number;  
};  
type AType = ValueTypeOfProperty<Obj, 'a'>;  
// AType 类型为 string   
6. 提取函数返回类型
type FunctionReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never;  
type ReturnType = FunctionReturnType<() => string>;  
// ReturnType 类型为 string
7. 提取联合类型中的各个类型
8. 创建类型变换(如数组转换成元组)

2. Exclude

Exclude<T, U>用于从类型 T 中排除所有可分配给类型 U 的成员。

c 复制代码
type T0 = Exclude<"a" | "b" | "c", "a" | "b">;  // "c"  
type T2 = Exclude<string | number | (() => void), Function>;  // string | number

3. Uppercase

ts的 内置条件类型,用于将字符转成大写

c 复制代码
type Greeting = "hello";  
type UppercaseGreeting = Uppercase<Greeting>; // 类型为 "HELLO"  
相关推荐
幽蓝计划11 分钟前
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
开发语言·harmonyos
CoderLiu14 分钟前
用这个MCP,只给大模型一个figma链接就能直接导出图片,还能自动压缩上传?
前端·llm·mcp
伍哥的传说16 分钟前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
海的诗篇_1 小时前
前端开发面试题总结-原生小程序部分
前端·javascript·面试·小程序·vue·html
小张成长计划..1 小时前
数据结构-栈的实现
开发语言·数据结构
uncleTom6661 小时前
前端地图可视化的新宠儿:Cesium 地图封装实践
前端
lemonzoey1 小时前
无缝集成 gemini-cli 的 vscode 插件:shenma
前端·人工智能
旷世奇才李先生1 小时前
Lua 安装使用教程
开发语言·lua
老家的回忆1 小时前
jsPDF和html2canvas生成pdf,组件用的elementplus,亲测30多页,20s实现
前端·vue.js·pdf·html2canvas·jspdf
Zonda要好好学习1 小时前
Python入门Day2
开发语言·python