![](/img/trans.png)
[英]TypeScript: generically infer union type member based on a string literal property
[英]Typescript infer parent type based on nested member
Typescript可以根據您在if語句中提出的問題來推斷值的類型。 例如,可以基於另一個推斷對象的一個成員:
type ChildType = 'a' | 'b';
type Child<T extends ChildType> = T extends 'a' ? { type: 'a', color: 'blue' } : T extends 'b' ? { type: 'b', color: 'red' } : never;
interface Parent<T extends Child<ChildType>> {
child: T extends Child<infer R> ? Child<R> : never;
}
function test<T extends Parent<Child<any>>>(parent: T) {
if (parent.child.type === 'a') {
parent.child.color === 'red'; // complains because should be blue
}
}
但是,使用類型的嵌套成員執行相同的檢查,它似乎不提供相同的效果。
type ChildType = 'a' | 'b';
interface BaseParent<T extends Child<ChildType>> {
child: T;
}
interface Child<T extends ChildType> {
type: T;
}
type Parent<T extends ChildType>
= T extends 'a' ? { color: 'blue' } & BaseParent<Child<'a'>>
: T extends 'b' ? { color: 'red', opacity: 2 } & BaseParent<Child<'b'>>
: never;
function test<T extends Parent<ChildType>>(parent: T) {
if (parent.child.type === 'a') {
parent.color === 'red' // should complain, but doesn't
}
}
這可以很容易地使用類型防護來糾正,但是我正在尋找一種沒有它們的方法。
首先要做的事情是 - 父子數據依賴於它的孩子可能是不合適的架構。 依賴性應該下降。 你可以從一開始就考慮它。
但如果你願意的話,我會這樣做(我添加了動物示例,以便我更容易理解):
type AcceptedAnimal = 'dogs' | 'cats';
interface ParentBase {
accepts: AcceptedAnimal
}
interface Cat {
meows: boolean;
}
interface Dog {
race: string;
}
type Parent = DogOwner | CatOwner;
interface DogOwner extends ParentBase {
animal: Dog
}
interface CatOwner extends ParentBase {
animal: Cat;
}
function isDogOwner(parent: ParentBase): parent is DogOwner {
return parent.accepts === 'dogs';
}
function test(parent: Parent) {
if (isDogOwner(parent)) {
parent.animal.race; // ok
return;
}
parent.animal.meows; // ok;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.