真正的Tyepscript进阶(一)

122 阅读2分钟

前言

接触TS也有一段时间了。感觉会了,感觉又没学过。

感觉会了是因为写一个函数,知道如何去声明一个参数的类型,也知道如何去使用interface,type以及类似于Patial,Omit,Parameters等内置高级的泛型应用。

但是!!!每当看到开源库里面的TS。卧槽???还能这么玩???卧槽???我怎么看不懂???

所以又再次的重新学习TS,这系列的内容会记录平时在工作中或者开源库中看到的TS的用法来进行总结。

然后还要声明的一点是不会过多的去解释一些TS基本的东西

希望有朝一日,大家写TS就像写JS一样的6

题目一

type Foo = {
 anumber;
 b?: string;
 cboolean;
}

type SomeOptional = SetOptional<Foo'a' | 'b'>;

// 实现SetOptional得到以下的结果

// type SomeOptional = {
//  a?: number; // 该属性已变成可选的
//  b?: string; // 保持不变
//  c: boolean; 
// }

刚看到这个题的时候,无非是涉及到泛型,以及泛型的约束,以及Patial的应用

type SetOptional<T,K extends keyof T> = ...

// 这里应该看得懂吧 忘记了这是基础的东西,不过多解释

现在无非是让K变成可选的,然后把原本T里面的东西保持不变,涉及到Pick,Patial,Exclude的应用。

type Dictinalry<T> = {
    [P in keyof T ] : T[P]
}
type SetOptional<T,K extends keyof T> = Dictinalry<Partial<Pick<T, K>> & Pick<T, Exclude<keyof T, K>>>>
type SomeOptional = SetOptional<Foo'a' | 'b'>;

// Partial<Pick<T, K>> 这部分得到的结果是 {a?:number,b?:string}

// Exclude<keyof T, K> 这部分得到的结果是 'c'

// Pick<T, Exclude<keyof T, K>> 这部分{c:boolean}


// 因此可以得到最终的结果

题目二

有了上面一题的铺垫,相信大家已经掌握了。来试试下面的

type Foo = {
 a?: number;
 bstring;
 c?: boolean;
}


type SetRequired<T, K extends keyof T> = ...
// 测试用例
type SomeRequired = SetRequired<Foo'b' | 'c'>;
// type SomeRequired = {
//  a?: number;
//  b: string; // 保持不变
//  c: boolean; // 该属性已变成必填
// }

题目三

这个应用是在Koa 获取参数类型那一部分看到的。具体Koa的下一篇文章来,这次先练练手

type Trim<T extends string> = // 

// 测试用例
Trim<' semlinker '>
//=> 'semlinker'

// 其实就是去除空格的一个功能 

这里其实就是对infer这个关键字的应用。想TS内置的高级类型中,如Parameters ConstructorParameters ReturnType中都有infer的使用。

// 目标是去除类型的左右空格
// 那先去除左边的空格
type TrimLeft<T extends string> = T extends ` ${infer P}`? TrimLeft<P> :P 

type TrimRight<T extends string> = T extends `${infer P} `? TrimRight<P> :P 

// 注意${infer P}这个前面是有个空格的

// 因此最终

type Trim<T extends string> = TrimLeft<TrimRight<V>>;

结束语

日积跬步,足以至千里。今天先这样了。