highlight: an-old-hope theme: condensed-night-purple ---T
目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
1. Medium Readonly 2. Medium Deep Readonly 3. Medium tuple union
01. Medium Readonly
题目要求
import { Alike, Expect } from '@type-challenges/utils'
type cases = [
Expect<Alike<MyReadonly2<Todo1>, Readonly<Todo1>>>,
Expect<Alike<MyReadonly2<Todo1, 'title' | 'description'>, Expected>>,
Expect<Alike<MyReadonly2<Todo2, 'title' | 'description'>, Expected>>,
]
interface Todo1 {
title: string
description?: string
completed: boolean
}
interface Todo2 {
readonly title: string
description?: string
completed: boolean
}
interface Expected {
readonly title: string
readonly description?: string
completed: boolean
}
我的答案
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [key in K]: T[key];
} & {
[key2 in MyExclude<keyof T, K>]: T[key2];
};
知识点
1. 在使用ts对象的mapped语法的时候可以参杂Exclude等关键字
2. Medium Deep Readonly
题目要求
import { Equal, Expect } from "@type-challenges/utils";
type cases = [Expect<Equal<DeepReadonly2<X>, Expected>>];
type X = {
a: () => 22;
b: string;
c: {
d: boolean;
e: {
g: {
h: {
i: true;
j: "string";
};
k: "hello";
};
};
};
};
type Expected = {
readonly a: () => 22;
readonly b: string;
readonly c: {
readonly d: boolean;
readonly e: {
readonly g: {
readonly h: {
readonly i: true;
readonly j: "string";
};
readonly k: "hello";
};
};
};
};
我的解答
type Primitive = string | number | boolean;
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends Primitive | Function
? T[K]
: DeepReadonly<T[K]>;
};
type DeepReadonly2<T> = {
readonly [K in keyof T]: keyof T[K] extends never ? T[K] : DeepReadonly2<T[K]>;
};
知识点
Q1:如何判断一个类型是一个对象?
A1:使用keyof T extends never来判断
3. Medium tuple union
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<TupleToUnion<[123, '456', true]>, 123 | '456' | true>>,
Expect<Equal<TupleToUnion<[123]>, 123>>,
]
我的解答
type TupleToUnion<T extends any[]> = T extends (infer P)[] ? P : never;
知识点
1. 上述情况中,T extends (infer P)[]推断出来的就是一个泛型,而T extends infer P推断的是一个数组