首页 > 其他分享 >ts的类型工具

ts的类型工具

时间:2024-04-29 14:24:28浏览次数:22  
标签:返回 string number ts 类型 工具 type 键名

看了一遍阮一峰的ts文档,地址:https://wangdoc.com/typescript/utility#capitalizestringtype。ts提供了一些类型工具,在此记录一下,做个总结,加深印象。

字符串的类型工具4种:

Uppercase<S> 字母大写

Lowercase<S> 字母小写

Capitalize<S> 首字母大写

Uncapitalize<S> 首字母小写

其他类型有18种,但其中的3种 OmitThisParameter<Type>ThisParameterType<Type>ThisType<Type>主要是用于this的处理,应用场景少见,所以就不加强记忆了,剩下的15种,我根据处理的类型,即工具入参类型进行分类:

         1. 处理Promise,即工具入参为Promise,有1种

    1)Awaited<Promise>    

         2.处理构造函数,有2种

    1)ConstructorParameters<Class>

    2)InstanceType<Class>    

         3. 处理对象类型,有6种

    1)Omit<Object,K>

    2)Pick<Object,K>

    3)Readonly<Object>

    4)ReadonlyArray<T>

    5)Partial<Object> 

    6)Required<Object>  

         4. 处理方法,有2种
    1)Parameters<Function>

    2)ReturnType<Function>  

         5. 处理联合类型,有4种

    1)Exclude<T,U>

    2Extract<T,U>

    3NonNullable<T>

    4)Record<K,T> 

1. Awaited<P> 返回promise的数据类型

Awaited<P>用来取Promise的返回值,比如描述.then()和await方法返回值。

type DataType = {
  code: number,
  data: string,
  msg: string
}

export function getDataById(): Promise<DataType> {
  return new Promise((resolve) => {
    resolve({
      code: 0,
      data: "我是返回的数据",
      msg: "success"
    })
  })
}

/* 两种A的定义都可以,相当于 type A = DataType */
// type A = Awaited<Promise<DataType>>
type A = Awaited<ReturnType<typeof getDataById>>
const data: A = {
  code: 0,
  data: "",
  msg: ""
}

2. ConstructorParameters<Class> 提取构造方法的参数类型,并通过元组类型返回

ConstructorParameters<C>入参是一个构造方法,可以new的,它用于将new时传入的参数类型提取出来,并用一个数组合并返回。

class Demo {
  constructor(x: number, y: string) { }
}
/* 相当于 A = [x:number,y:string] */
type A = ConstructorParameters<typeof Demo>
const data1: A = [1, "字符串"]

/* 相当于 A = [x:number,y?:string] */
type B = ConstructorParameters<new (x: number, y?: string) => object>
const data2: B = [1]
const data3: B = [1,"我是可填的字符串"]

3. InstanceType<Class> 提取构造函数的返回值的类型,也就是返回实例类型

 InstanceType<Class>入参是一个构造函数,返回的是这个实例

class Demo {
  constructor(x: number, y: string) { }
}
type Z = InstanceType<typeof Demo>
// 以下两种写法意义一样
const demo1: Z = new Demo(1, "1")
const demo2: Demo = new Demo(2, "bbb")

4. Pick<Object,T> 从对象类型中,挑出T中指定的键名,返回一个新的对象类型

从对象类型Object中,挑选出联合类型T中的键名,将挑选出来的组成一个新的对象类型进行返回。注意:T必须是对象类型中已经存在的键名,不然会报错的。

type O = {
  name: string,
  address: string,
  otherInfo: {
    hobby: string,
    desc: string
  }
}
/* 相当于 P1 = {name:string,address:string} */
type P1 = Pick<O, 'name' | 'address'>
const p: P1 = {
  name: "张三",
  address: "中国"
}
/* 报错了,noExist这个键名不存在O中 */
type P2 = Pick<O, 'name' | 'noExist'> 

Pick的实现如下:

type Pick<O,T extends keyof O> = {
  [P in T]:O[p]  
}

从实现中能看到,T必须是O存在的键名,不然读取O[P]就要报错了,那我们调整一下,传的T可以是O不存在的键名,最后返回结果与Pick一样。

/* P为T与O键名的交叉集,这样就保证键名P一定存在于O */
type PickAdjust<O, T extends keyof any> = {
  [P in Extract<T, keyof O>]: O[P]
}

再调整一下,改为可以传不存在的键名,不存在的键名就给定any类型。

/* 
  允许T任何类型,然后再通过extends ? 三木运算符给值
  如果再严谨一点,改为 T extends keyof number|string|symbol
*/
type PickAdjust<O, T extends keyof any> = {
  [P in T]: P extends keyof O ? O[P] : any
}
type O = {   name: string,   address: string,   otherInfo: {     hobby: string,     desc: string   } } // P = {name:string,age:any}   type P = PickAdjust<O, "name" | 'age'> const p: P = {   name: "",   age: "" }
 

5. Omit<Object,T> 从对象类型中,去掉T中指定的键名,返回一个新的对象类型

Omit<Object,T>,从对象类型中,剔除T有提过的键名,返回一个新的对象,这跟Pick相反,一个是留,一个是去。

type O = {
  name: string,
  address: string,
  otherInfo: {
    hobby: string,
    desc: string
  }
}
/* 
  M相当于O去掉了name和noexist属性
  去掉的键名中传O中不存在的键名也是没关系的
*/
type M = Omit<O, 'name' | 'noExist'>
const m: M = {
  address: "中国",
  otherInfo: {
    hobby: '保护世界',
    desc: '世界和平'
  }
}

Omit<Object,T> 实现如下:

type Omit<O, T> = Pick<O, Exclude<keyof O, T>>

6. Partial<Object> 将对象的所有属性都变为可选,返回一个新的对象类型

Partial<Object>将对象所有属性都变为可选,K?:T

type O = {
  name: string,
  address: string,
  otherInfo: {
    hobby: string,
    desc: string
  }
}
/* O中所有的属性都变为可选 */
type X = Partial<O>
const x: X = {
  name: "张三"
}

!!! 注意,属性的类型如果为对象类型,那还是按照它自身的情况规定可选或必选,这玩意不能传递哈
就比如上面的otherInfo是可选的,但如果你选了它,那它的【hobby】【desc】是必选的,这不能传递到下面。

Partial<Object>实现如下:

type Partial<O> = {
  [P in keyof O]?: O[P]
}

7. Required<Object>将对象的所有属性都变为必选,返回一个新的对象类型

Required<Object>将对象所有属性都变为必选,与Partial<Object>相反,K-?:T,将这?减掉

type O = {
  name: string,
  age?: number,
  otherInfo: {
    hobby?: string,
    desc: string
  }
}
type R = Required<O>
/* 
  上面O中的age可选,变为了必选
  但otherInfo中的hobby还是可选,不会被影响,因为这个不会传递
*/
const r: R = {
  name: "李四",
  age: 18,
  otherInfo: {
    desc: "世界和平"
  }
}

Required<Object>实现如下:

type Required<O> = {
  [P in keyof O]-?: O[P]
}

8. Readonly<Object> 将对象的所有属性都变为只读,返回一个新的对象类型

Readonly<Object>将对象所有属性都变为只读,readonly  K:T ,如果是去掉只读,可以写 readonly  K:T

type O = {
  name: string,
  age?: number,
  otherInfo: {
    hobby?: string,
    desc: string
  }
}
type R = Readonly<O>
const r: R = {
  name: "李四",
  age: 18,
  otherInfo: {
    desc: "旧的描述"
  }
}
/* 报错 name属性只读,不可赋值 */
r.name = "123"
/* 正确 因为只读标志不会传递 */
r.otherInfo.desc = "新的描述"

Readonly<Object>实现如下:

type Readonly<O> = {
  readonly [P in keyof O]: O[P]
}

9. ReadonlyArray<T>用来生成一个只读数组

ReadonlyArray<T>数组只读,不可再修改数组,它的push,splice,pop等都不存在不可用

const values: ReadonlyArray<string>  = ['a', 'b', 'c'];
values[0] = 'x'; // 报错
values.push('x'); // 报错
values.pop(); // 报错
values.splice(1, 1); // 报错

ReadonlyArray<T>实现如下:

interface ReadonlyArray<T>{
  readonly length:number
  readonly [n:number]:T
}

10. Parameters<Function>提取方法的入参类型,返回一个元组类型

Parameters<Function>接收一个函数类型,将入参提取出来,并组合为元组类型进行返回。如果该函数没有入参,那就返回一个空数组。

function JoinArg(x: number, y: string): string {
  return x + y
}
/* A = [number,string] */
type A = Parameters<typeof JoinArg>
const a: A = [1, ""]

/* B = [] */
type B = Parameters<() => {}>
const b: B = []

Parameters<Function>实现如下:

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never

11. ReturnType<Function>返回方法的返回值的类型

ReturnType<Function>接受一个函数类型,返回函数返回值的类型。

type R1 = ReturnType<() => void> // void
type R2 = ReturnType<() => {}> // {}
type R3 = ReturnType<() => { x: number, y: string }> // {x: number, y: string }
type R4 = ReturnType<() => Array<string>> // Array<String>

ReturnType<Function>实现如下:

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never

12. Exclude<U,E>从U中剔除E,组合新的类型返回

Exclude<U,E>用来从联合类型U中,剔除某些类型E,组合成一个新的类型返回。可以理解为 U-E的值,如果E中有U不包含的,直接忽略。

type A = number | string | Array<string>
type B = number | boolean
type T1 = Exclude<A, B> // number | Array<string>
type T2 = Exclude<200 | 400, 200 | 201>; // 400
type T3 = Exclude<number, boolean>; // number
type T4 = Exclude<string | string[], any[]>; // string
type T5 = Exclude<(() => void) | null, Function>; // null

Exclude<U,T>实现如下:

type Exclude<U,T> = U extends T ? never:U

其实看到实现时候,我有点误解,Exclude<number|string,number|boolean>结果是string,我有点问题,我觉得按照它实现来理解的话, number|string extends number|boolean 结果是false,所以结果应该是U,也就是应该为number|string,为啥结果是string。

后来请教朋友,说是联合类型,会拆开来去extends,然后再汇集,也就是说,上面的相当于number extends number|boolean,结果true,得到never;string extends number|boolean,结果false,得到string,集合的结果就是never|string,由于never类型是任何其他类型的子类型,它跟其他类型组成联合类型时,可以直接将never类型从联合类型中消掉,所以结果就是string。

13. Extract<U,E>从U中提取出与E的交集,组合新的类型返回

Extract<U,E>从联合类型U中取出E提到的类型,组合成一个新的类型返回。如果E提到的类型在U中不存在,直接忽略。它跟Exclude相反

type T1 = Extract<'a'|'b'|'c', 'a'>; // 'a'
type T2 = Extract<'a'|'b'|'c', 'a'|'b'>; // 'a'|'b'
type T3 = Extract<'a'|'b'|'c', 'a'|'d'>; // 'a'
type T4 = Extract<string | string[], any[]>; // string[]
type T5 = Extract<(() => void) | null, Function>; // () => void
type T6 = Extract<200 | 400, 200 | 201>; // 200

Extract<U,E>实现如下:

type Extract<U, T> = U extends T ? U : never

14. NonNullable<U>从U中剔除null,undefined类型,组合新的类型返回

NonNullable<U>返回非空类型,从联合类型中剔除null,undefined类型。

// string|number
type T1 = NonNullable<string|number|undefined>;

// string[]
type T2 = NonNullable<string[]|null|undefined>;

type T3 = NonNullable<boolean>; // boolean
type T4 = NonNullable<number|null>; // number
type T5 = NonNullable<string|undefined>; // string
type T6 = NonNullable<null|undefined>; // never

NonNullable<T>实现如下:

type NonNullable<T> = T & {}

由于 TypeScript 的非空值都属于Object的子类型,所以会返回自身;而nullundefined不属于Object,会返回never类型。

15. Record<K,T>K作为键名,T作为键值,组合为一个新的对象类型返回

Record<K,T>将联合类型K作为对象类型的键名,T作为键值,组成一个新的对象类型进行返回。

type T = Record<'a', number>;// {a:number}

type T = Record<'a'|'b', number>;// { a: number, b: number }

type T = Record<'a', number|string>;// { a: number|string }

Record<K,T>实现如下:

type Record<K extends string|number|symbol,T>={
  [P in K]:T  
}

16.1. Uppercase<StringType> 字母大写

16.2. Lowercase<StringType> 字母小写

16.3. Capitalize<StringType> 首字母大写

16.4. Uncapitalize<StringType> 首字母小写

type A = 'hello';
type B = Uppercase<A>;// "HELLO"



type A = 'HELLO';
type B = Lowercase<A>;// "hello"



type A = 'hello';
type B = Capitalize<A>;// "Hello"



type A = 'HELLO';
type B = Uncapitalize<A>;// "hELLO"

 

标签:返回,string,number,ts,类型,工具,type,键名
From: https://www.cnblogs.com/grow-up-up/p/18164004

相关文章

  • go语言数据类型转换
    go语言数据类型转换golang不会对数据进行隐式的类型转换,只能手动去执行转换操作,表达式T(v)将值v转换为类型TT:就是数据类型V:就是需要转换的变量一、数值类型转换数值间转换的时候建议从小范围转换成大范围,比如int8转int16,大范围转换成小范围的时候,比如int16转int8,会发......
  • vite 项目,背景图报错 The request url "xx/xx/xx.xx" is outside of Vite serving all
    版本vite3.2.6vue3.2.37 背景本地启项目,项目中引用了自研组件库(没有安装,通过文件路径直接引用,便于调试项目和组件),两者文件夹是平级的组件库中背景图:background:100%/100%no-repeaturl('../assets/svg/xxx.svg'); 问题本地启动项目之后,背景图未正常展示浏览器控......
  • Redis中对数组的获取类型转换
    1#####Redis中对数组的获取类型转换23```java4//判断redis中键值key是否存在;5BooleancarWeizi_redis_service=redisService.hasKey("carWeizi_redis_service");6if(carWeizi_redis_service){7//获取对应的list数组传入时re......
  • 界面组件DevExpress Blazor UI v23.2 - 网格、工具栏功能全新升级
    DevExpress BlazorUI组件使用了C#为BlazorServer和BlazorWebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生BlazorUI组件(包括PivotGrid、调度程序、图表、数据编辑器和报表等)。DevExpress Blazor控件目前已经升级到v23.2版本了,此版本进一步增强了可访问......
  • 一个开源轻量级的C#代码格式化工具(支持VS和VS Code)
    前言C#代码格式化工具除了ReSharper和CodeMaid,还有一款由.NET开源、免费(MITLicense)、轻量级的C#语言代码格式化工具:CSharpier。工具介绍CSharpier是一款开源、免费、轻量级的C#语言代码格式化工具。它使用Roslyn来解析你的代码,并根据其自身的规则重新格式化代码。工具支持IDE......
  • Echarts制作时变数据可视化+2024 QQ群聊记录制作词云图
    时变数据可视化Echarts其实就是个js文件,在开头导入一下就好了其实这部分我没有做太多时间,大部分代码都是gpt直接生成的(乐)所以这里只分享一下我觉得代码里比较有意思的部分先放效果图图中渐变效果的代码(来源CSDN某个博主)lineStyle:{shadowCo......
  • 为什么MySQL不是数据库类型
    MySQL实际上是一个关系型数据库管理系统(RDBMS),而不是一个数据库类型。这里的关键在于理解“数据库类型”和“数据库管理系统”之间的区别。数据库类型:通常指的是数据库模型或数据结构的分类,比如关系型数据库(如MySQL、Oracle、SQLServer等)和非关系型数据库(如MongoDB、Redis、C......
  • SpriteAtlas图集导出工具
      publicclassSpriteAtlasExportTool:EditorWindow{conststringMenuItemPath_ExportSelectSpriteAtlas="MyTools/ExportSelectSpriteAtlas";[MenuItem(MenuItemPath_ExportSelectSpriteAtlas,true)]privatestaticboolMenuItemV......
  • 第二章 标准数据类型
    1.六大标准数据类型1.1Number(数字类型)#(1)int整型(正整型,0,负整形)#二进制整型intvar=0b110#八进制整型intvar=0o127#十进制整型intvar1=100intvar2=0intvar3=-10#十六进制整型intvar=0xff#(2)float浮点型(小数)#表达式1floatvar=3.6#......
  • start windows executable in multi-process and wait its ending
    theexecutableimporttimeimportrandomimportsystime.sleep(random.random())print(sys.argv[1])thecallingcontrolimportsubprocessll=[]foriiinrange(8):ll.append(subprocess.Popen(f"pythonab.pymk{ii}"#maybesom......