提问人:kohloth 提问时间:11/16/2023 更新时间:11/16/2023 访问量:20
如何让 TS 使用递归判别联合进行类型推断?
How to get TS to do type inference with recursive discriminated unions?
问:
我可以在 TS 中使用什么机制让 TS 使用递归判别联合进行类型推断?
给出下面的例子:
interface Circle {
type: 'circle';
radius: 3;
}
interface Square {
type: 'square';
sides: 4;
}
interface Bag {
type: 'bag';
color: 'green';
children: AnyItem[];
}
type AnyItem = Circle | Square | Bag;
interface CircleConstructorParams {
type: 'circle';
}
interface SquareConstructorParams {
type: 'square';
}
interface BagConstructorParams {
type: 'bag';
children: AnyConstructorParams[];
}
type AnyConstructorParams = CircleConstructorParams | SquareConstructorParams | BagConstructorParams;
function getItem(itemConstructorParams: AnyConstructorParams) {
if (itemConstructorParams.type === 'circle') {
const circle: Circle = {
type: 'circle',
radius: 3,
};
return circle;
} else if (itemConstructorParams.type === 'square') {
const square: Square = {
type: 'square',
sides: 4,
};
return square;
} else if (itemConstructorParams.type === 'bag') {
const bag: Bag = {
type: 'bag',
color: 'green',
children: itemConstructorParams.children.map(child => {
return getItem(child);
})
};
return bag;
}
throw new Error('Invalid');
}
const circle = getItem({ type: 'circle' });
console.log(circle.radius);
const square = getItem({ type: 'square' });
console.log(square.sides);
const nested = getItem({
type: 'bag',
children: [
{ type: 'square', },
{ type: 'circle', },
{
type: 'bag',
children: [
{ type: 'square' },
{ type: 'circle' },
]
},
],
});
console.log(nested.children[2].children[1].radius);
我收到以下错误:
Property 'radius' does not exist on type 'Circle | Square | Bag'.
Property 'radius' does not exist on type 'Square'.
Property 'sides' does not exist on type 'Circle | Square | Bag'.
Property 'sides' does not exist on type 'Circle'.
Property 'children' does not exist on type 'Circle | Square | Bag'.
Property 'children' does not exist on type 'Circle'.
鉴于我使用了文字成员、类型保护和类型化返回对象,我希望 TS 能够从每个嵌套的“Item 构造函数”推断每个嵌套“Item”的类型。
以这种方式使用 TS 无法推断类型的原因是什么,正确的方法是什么,同时避免执行以下操作:
console.log((((nested as Bag).children[2] as Bag).children[1] as Circle).radius);
答: 暂无答案
评论