一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第25天,点击查看活动详情。
题目四十:requiredbykeys
// template.ts
type RequiredByKeys<T, K> = any
// test-cases.ts
import type { Equal, Expect } 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>>>,
]
实现一个通用的 RequiredByKeys<T,K>,它接受两种类型的参数 T 和 K。
K指定应设置为必需的T属性集。当没有提供 K 时,它应该使所有所需的属性都像正常的 required<T> 一样。
测试用例
User 中有三项,都是可选属性
RequiredByKeys<User, 'name'>
将 User 中 key 为 name 的项改为必填的
RequiredByKeys<User, 'name' | 'unknown'>
unknown 会被忽略
RequiredByKeys<User, 'name' | 'age'>
如果传入的是联合属性,则将联合属性中的每一项都改为必填
RequiredByKeys<User>
如果没传第二个参数,则和 Required 方法效果一致
required
我们先来看一下 TS 内置的 required 方法
type Required<T> = {
[P in keyof T]-?: T[P];
};
作用:将全部项都外给必填(去掉可选 ?)
代码实现
- 原代码
type RequiredByKeys<T, K> = any
K的默认值是T的全部key
type RequiredByKeys<T, K = keyof T> = any
- 拿出
T中key为K的内容
type RequiredByKeys<T, K = keyof T> = Pick<T, K & keyof T>
- 将其转换为必填的
type RequiredByKeys<T, K = keyof T> = Required<Pick<T, K & keyof T>>
- 与剩余的
T中的内容合并
type RequiredByKeys<T, K = keyof T> = Required<Pick<T, K & keyof T>>
& Omit<T, K & keyof T>
- 因为使用了合并,所以需要在复制一下
type Copy<T> = {
[P in keyof T]: T[P]
}
type RequiredByKeys<T, K = keyof T> = Copy<
Required<Pick<T, K & keyof T>>
& Omit<T, K & keyof T>
>
题目四十一:mutable
// template.ts
type Mutable<T> = any
// test-cases.ts
import type { Equal, Expect } from '@type-challenges/utils'
interface Todo1 {
title: string
description: string
completed: boolean
meta: {
author: string
}
}
type cases = [
Expect<Equal<Mutable<Readonly<Todo1>>, Todo1>>,
]
实现通用的Mutable<T>,它使T中的所有属性都是可变的(而不是只读的)。
代码实现
- 原代码
type Mutable<T> = any
- 遍历对象
type Mutable<T> = {
[P in keyof T]: T[P]
}
- 在遍历过程中,祛除
readonly修饰符
type Mutable<T> = {
- readonly [P in keyof T]: T[P]
}