我有这个界面:
export interface UserSettings
{
one: {
three: number;
four: number;
};
two: {
five: number;
six: number;
};
}
Run Code Online (Sandbox Code Playgroud)
...并想把它变成这个:
export interface UserSettingsForUpdate
{
one?: {
three?: number;
four?: number;
};
two?: {
five?: number;
six?: number;
};
}
Run Code Online (Sandbox Code Playgroud)
......但Partial<UserSettings>产生了这个:
{
one?: {
three: number;
four: number;
};
two?: {
five: number;
six: number;
};
}
Run Code Online (Sandbox Code Playgroud)
是否可以使用映射类型使所有深度上的所有属性都可选,或者我是否必须手动创建接口?
Jef*_*son 34
随着2.8中的条件类型的登陆,我们现在可以声明一个递归的部分类型,如下所示.
type RecursivePartial<T> = {
[P in keyof T]?:
T[P] extends (infer U)[] ? RecursivePartial<U>[] :
T[P] extends object ? RecursivePartial<T[P]> :
T[P];
};
Run Code Online (Sandbox Code Playgroud)
参考:
http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html
Mei*_*hes 17
你可以制作自己的映射类型,如下所示:
type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
Run Code Online (Sandbox Code Playgroud)
不幸的是,这对于数组类型的字段不起作用.似乎还没有办法进行条件类型映射; 即限制原语.请参阅https://github.com/Microsoft/TypeScript/pull/12114#issuecomment-259776847现在可以,请参阅其他答案.
Joo*_*oon 10
我制作了一个库tsdef,它有许多这样的常见模式/片段。
对于这种情况,您可以像下面这样使用它:
import { DeepPartial } from 'tsdef';
let o: DeepPartial<{a: number}> = {};
Run Code Online (Sandbox Code Playgroud)
小智 9
所提供的解决方案都不够好。这是一个解释:
const x: RecursivePartial<{dateValue: Date}> = {dateValue: 0}; // ja-ja-ja
Run Code Online (Sandbox Code Playgroud)
在上面的代码中, 的实际类型dateValue允许RecursivePartial<Date> | undefined分配任何值!的预期类型dateValue是 just Date,但规则T[P] extends object ? RecursivePartial<T[P]>太宽泛。
解决方案是分离原语并消除extends object:
export type RecursivePartial<T> = {
[P in keyof T]?:
T[P] extends Array<infer U> ? Array<Value<U>> : Value<T[P]>;
};
type AllowedPrimitives = boolean | string | number | Date /* add any types than should be considered as a value, say, DateTimeOffset */;
type Value<T> = T extends AllowedPrimitives ? T : RecursivePartial<T>;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4044 次 |
| 最近记录: |