[TypeScript] 类型挑战 - 简单难度个人题解

826 阅读2分钟

题目地址:github

在线编辑器:TypeScript Playground

1. Pick

type MyPick<T, K extends keyof T> = {
  [key in K]: T[key];
}

2. Readonly

type MyReadonly<T> = {
  readonly [K in keyof T]: T[K];
}

3. Tuple to Object

提供一个数组,实现一个工具类型,其结果类型的key type都是数组的元素

type TupleToObject<T extends readonly any[]> = {
  [K in T[number]]: K
}

在ts里面类型也是可以使用索引来访问。特别的,数组类的相关类型可以使用明确的数字下标或者number进行索引,使用number就是得到数组内所有的元素类型

详情请阅读:www.typescriptlang.org/docs/handbo…

// as const是必须的,它将数组固化为一个拥有字面量类型的元组类型
// 这样在类型索引的时候才是明确的字面量类型,否则就是对数组元素进行typeof操作了
const arr = ['number', 'string', 'object'] as const;

type ArrFirst = typeof arr[0]; // 'number'
type ArrAll = typeof arr[number]; // 'string' | 'number' | 'object'

所以这里的T[number]就是得到元组内元素的联合字面量类型,再使用in得到每一个类型

4. First of Array

// 我的第一版答案,没有考虑空数组,所以这个答案如果传入空数组得到的结果就是undefined
// 如果undefined也是意料结果的话也不是不可以
// type First<T extends any[]> = T[0];

type First<T extends any[]> = T extends [] ? never : T[0];

这里使用了条件类型,可以参照三元表达式。详情请阅读:www.typescriptlang.org/docs/handbo…

5. Length of Tuple

// 这里同上,看情况判断是否接受空元组
type Length<T extends readonly any[]> = T['length'];

6. Exclude

Exclude是针对联合类型,官方定义:Constructs a type by excluding from Type all union members that are assignable to ExcludedUnion

type MyExclude<T, U> = T extends U ? never : T;

7. Awaited

拿到Promise<T>的返回值类型

type Awaited<T> = T extends Promise<infer R> ? R : T;

infer相当于在条件类型里面声明的一个类型变量,上面的意思就是:如果T能够符合Promise<infer R>,那么返回R

参考资料:jkchao.github.io/typescript-…

8. if

三元判断

type If<C extends true | false, T, F> = C extends true ? T : F;

9. Concat

实现类似数组的Concat类型

type Concat<Arr1 extends any[], Arr2 extends any[]> = [...Arr1, ...Arr2];

10. Includes

实现类似数组的Includes类型

type Includes<Arr extends any[], El> = El extends Arr[number] ? true : false;

11. Push

type Push<Arr extends any[], El> = [...Arr, El];

12. Unshift

type Unshift<Arr extends any[], El> = [El, ...Arr];

13. Parameters

type MyParameters<F extends Function> = F extends (...args: infer R) => any ? R : never;

如有错误,欢迎批评指正