我遇到了一个键入React组件的问题,这是我以前从未遇到过的。我已经简化了下面的问题。
interface Circle {
kind?: "circle";
radius: number;
}
interface Square {
kind: "square";
sideLength: number;
}
type Shape = Circle | Square;
const shape: Shape = {
sideLength: 7,
radius: 7,
};
指向包含上述
的TypeScript Playground的链接在上面的例子中,我希望shape
变量声明在TypeScript中抛出一个错误,因为Circle和Square都没有一个sideLength
和一个radius
。定义的对象既不是圆形也不是正方形,所以在我看来,它不应该是一个有效的形状。
是否可以这样定义类型,使下列项目是有效的或错误的(如标记的)?
// Valid
const shape: Shape = {
kind: 'circle',
radius: 7,
};
// Valid
const shape: Shape = {
radius: 7,
};
// Valid
const shape: Shape = {
kind: 'square',
sideLength: 7,
};
// Error
const shape: Shape = {
sideLength: 7,
radius: 7,
};
// Error
const shape: Shape = {
sideLength: 7,
};
// Error
const shape: Shape = {
kind: 'square',
radius: 7,
};
// Error
const shape: Shape = {
kind: 'circle',
sideLength: 7,
};
编辑:
为了进一步澄清,在我的用例中,kind
在Circle上是可选的。对于那些熟悉React的人来说,我试图解决的实际问题是围绕样式组件暴露的as
属性。我想要一个组件接受可选的as
道具,这将允许用户将组件(默认为button
)更改为链接(a
)。如果用户指定了as="a"
,那么我希望TypeScript能够比较用户是否尝试在现在的链接(例如disabled
)上使用特定于按钮的道具。as
道具是可选的,因为我不希望所有实现者都被要求传递它。在我上面的简化示例中,as
类似于kind
,这就是为什么kind
是可选的。
注意,您已经将kind
属性定义为可选属性,因此,如果您创建的形状对象中只有radius
属性仍然有效,那么circle
:
看这个东西
const shape: Shape = {
sideLength: 7,
radius: 7,
};
这是一个有一个额外属性的有效圆。
所以在某些情况下你说,你应该把kind
属性作为一个必需的属性:
interface Circle {
kind: "circle";
radius: number;
}
interface Square {
kind: "square";
sideLength: number;
}
type Shape = Circle | Square;
const shape2: Shape = {
radius: 7,//Error
};
PlaygroundLink