我正在try 创建一种在不同阶段逐步填充的类型.例如,在创建一个Bar
对象时,我希望Data<DataType.bar>
包含一个完整的Foo
对象,但Bar
本身和Baz
都不是Data
的一部分:
enum DataType {
'foo',
'bar',
'baz',
}
type Foo = {
a: string;
};
type Bar = {
b: string;
};
type Baz = {
c: string;
};
type Data<T extends DataType | null = null> = {
[DataType.foo]: T extends DataType.bar | DataType.baz | null ? Foo : never;
[DataType.bar]: T extends DataType.baz | null ? Bar : never;
[DataType.baz]: T extends null ? Baz : never;
};
const myData: Data = {
[DataType.foo]: { a: 'I should already exist while bar is being created' },
/*
[DataType.bar]: {
b: `I correctly error when uncommented...
but when commented, DataType.bar also appears to be required?`
}
*/
};
尽管当包含DataType.bar
时,myData
正确地包含了一个错误,但当它被注释掉时,我也会得到以下错误:
Type '{ 0: { a: string; }; }' is missing the following properties from type 'Data<DataType.bar>': [DataType.bar], [DataType.baz]
个
有没有办法告诉TypeScrip,基于T extends DataType
个泛型,这些属性实际上并没有丢失?
EDIT:这似乎是我想要的,然而它看起来真的重复了吗?有没有更好的方法来做这件事?
type Data<T extends DataType | null = null> = T extends null
? {
[DataType.foo]: Foo;
[DataType.bar]: Bar;
[DataType.baz]: Baz;
}
: T extends DataType.baz
? {
[DataType.foo]: Foo;
[DataType.bar]: Bar;
}
: T extends DataType.bar
? {
[DataType.foo]: Foo;
}
: T extends DataType.foo
? {}
: never;