在TypeScript中,2.2 ......
假设我有一个Person类型:
interface Person {
name: string;
hometown: string;
nickname: string;
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个返回Person的函数,但不需要昵称:
function makePerson(input: ???): Person {
return {...input, nickname: input.nickname || input.name};
}
Run Code Online (Sandbox Code Playgroud)
应该是什么类型的input?我正在寻找一种动态方式来指定一个类型,Person除了nickname可选(nickname?: string | undefined)之外.到目前为止,我发现的最接近的是:
type MakePersonInput = Partial<Person> & {
name: string;
hometown: string;
}
Run Code Online (Sandbox Code Playgroud)
但这并不是我想要的,因为我必须指定所需的所有类型而不是可选的类型.
Tim*_*m K 40
这是我的 Typescript 3.5+ 可选实用程序类型
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
// and your use case
type MakePersonInput = Optional<Person, 'nickname'>
// and if you wanted to make the hometown optional as well
type MakePersonInput = Optional<Person, 'hometown' | 'nickname'>
Run Code Online (Sandbox Code Playgroud)
小智 30
你也可以这样做,只部分键.
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
interface Person {
name: string;
hometown: string;
nickname: string;
}
type MakePersonInput = PartialBy<Person, 'nickname'>
Run Code Online (Sandbox Code Playgroud)
Phi*_*ley 24
对于即插即用解决方案,请考虑使用出色的utility-types软件包:
npm i utility-types --save
Run Code Online (Sandbox Code Playgroud)
然后只需使用Optional<T, K>:
import { Optional } from 'utility-types';
type Person = {
name: string;
hometown: string;
nickname: string;
}
type PersonWithOptionalNickname = Optional<Person, 'nickname'>;
// Expect:
//
// type PersonWithOptionalNickname {
// name: string;
// hometown: string;
// nickname?: string;
// }
Run Code Online (Sandbox Code Playgroud)
Dal*_*onF 11
更新:
从TypeScript 2.8开始,条件类型更简洁地支持它!到目前为止,这似乎比以前的实现更可靠.
type Overwrite<T1, T2> = {
[P in Exclude<keyof T1, keyof T2>]: T1[P]
} & T2;
interface Person {
name: string;
hometown: string;
nickname: string;
}
type MakePersonInput = Overwrite<Person, {
nickname?: string;
}>
function makePerson(input: MakePersonInput): Person {
return {...input, nickname: input.nickname || input.name};
}
Run Code Online (Sandbox Code Playgroud)
和以前一样,MakePersonInput相当于:
type MakePersonInput = {
name: string;
hometown: string;
} & {
nickname?: string;
}
Run Code Online (Sandbox Code Playgroud)
已过期:
从TypeScript 2.4.1开始,看起来还有另一种选择,如GitHub用户ahejlsberg在类型减法的线程中所提出的:https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-307871458
type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
type Overwrite<T, U> = { [P in Diff<keyof T, keyof U>]: T[P] } & U;
interface Person {
name: string;
hometown: string;
nickname: string;
}
type MakePersonInput = Overwrite<Person, {
nickname?: string
}>
function makePerson(input: MakePersonInput): Person {
return {...input, nickname: input.nickname || input.name};
}
Run Code Online (Sandbox Code Playgroud)
根据Intellisense,MakePersonInput相当于:
type MakePersonInput = {
name: string;
hometown: string;
} & {
nickname?: string;
}
Run Code Online (Sandbox Code Playgroud)
看起来有点搞笑,但绝对可以完成工作.
在缺点方面,Diff在我开始了解它是如何工作之前,我需要盯着那种类型一段时间.
Pet*_*ieg 11
type -fest包有一个实用程序SetOptional- https://github.com/sindresorhus/type-fest/blob/main/source/set-optional.d.ts
import { SetOptional } from 'type-fest';
type PersonWithNicknameOptional = SetOptional<Person, 'nickname'>
Run Code Online (Sandbox Code Playgroud)
我发现该库维护良好,并且支持最新版本的打字稿。在我看来,值得添加到打字稿项目中。
Ale*_*min 10
如果您使用最新版本的打字稿,一个简单的解决方案是
function makePerson(input: Omit<Person, 'nickname'> & { nickname?: string }): Person {
return {...input, nickname: input.nickname || input.name};
}
Run Code Online (Sandbox Code Playgroud)
基本上,您从界面中删除“昵称”属性并将其重新添加为可选
如果你想确保它与原始界面保持同步,你可以这样做
Omit<Person, 'nickname'> & Partial<Pick<Person, 'nickname'>>
Run Code Online (Sandbox Code Playgroud)
如果您更改原始界面中的“昵称”属性,它会警告您
| 归档时间: |
|
| 查看次数: |
8109 次 |
| 最近记录: |