目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
01. Medium Required By Keys
题目要求
import { Equal, Expect, ExpectFalse, NotEqual } from "@type-challenges/utils";
interface User {
name?: string;
age?: number;
address?: string;
}
interface UserRequiredName {
name: string;
age?: number;
address?: string;
}
interface UserRequiredNameAndAge {
name: string;
age: number;
address?: string;
}
type cases = [
Expect<Equal<RequiredByKeys<User, "name">, UserRequiredName>>,
Expect<Equal<RequiredByKeys<User, "name" | "unknown">, UserRequiredName>>,
Expect<Equal<RequiredByKeys<User, "name" | "age">, UserRequiredNameAndAge>>,
Expect<Equal<RequiredByKeys<User>, Required<User>>>
];
我的答案
type MyRequired<T extends object> = {
[K in keyof T]-?: T[K];
};
type RequiredByKeys<
T extends object,
K extends any = never,
R extends object = isNever<K> extends true
? MyRequired<T>
: {
[key in Exclude<keyof T, K>]?: MyRequired<T>[key];
} & {
[key in Extract<K, keyof T>]: MyRequired<T>[key];
}
> = {
[key in keyof R]: R[key];
};
知识点
Q1: 如何去除 typescript 中的关键字,比如?和readonly等
A1:使用-这个关键字
2. Medium Mutable
题目要求
import { Equal, Expect, ExpectFalse, NotEqual } from "@type-challenges/utils";
interface Todo1 {
title: string;
description: string;
completed: boolean;
meta: {
author: string;
};
}
type cases = [Expect<Equal<Mutable<Readonly<Todo1>>, Todo1>>];
我的解答
type Mutable<R extends object> = {
-readonly [K in keyof Readonly<R>]: R[K];
};
知识点
- 使用
-关键字可以将一些修饰符减掉,达到我们的目的
3. Medium Omit By Type
题目要求
import { Equal, Expect, ExpectFalse, NotEqual } from "@type-challenges/utils";
interface Model {
name: string;
count: number;
isReadonly: boolean;
isEnable: boolean;
}
type cases = [
Expect<Equal<OmitByType<Model, boolean>, { name: string; count: number }>>,
Expect<
Equal<
OmitByType<Model, string>,
{ count: number; isReadonly: boolean; isEnable: boolean }
>
>,
Expect<
Equal<
OmitByType<Model, number>,
{ name: string; isReadonly: boolean; isEnable: boolean }
>
>
];
type CC = OmitByType<Model, boolean>;
我的解答
type OmitByType<T extends object, U, K extends keyof T = keyof T> = {
[key in K extends K ? (T[K] extends U ? never : K) : never]: T[key];
};
知识点
- 关键在于如何将一个对象真实的
key过滤出来,那些泛化的[key: string]过滤掉,使用K extends K这种方式 - 如果在遍历对象的时候剔除掉一个key,key返回是never就不会被计入其中