我想编写一个名为ProptyDontHaveChildren
的接口,它没有名为children
type ChildrenType = Array<number>
interface ProptyDontHaveChildren {
// doesn't have property called children
[index: string]: string;
}
interface WithChildren {
children: ChildrenType
}
type IntersectionType = ProptyDontHaveChildren & WithChildren;
function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType ) {
const newProps:IntersectionType = { children: children, ...props }
//TODO ...
}
如何定义TypeScript中没有某些属性的接口?
答案 0 :(得分:3)
这里有很多问题。警告:
您可以在children
中never
undefined
或ProptyDontHaveChildren
类型的可选属性(重要的是该属性是可选的):
type ChildrenType = Array<number>
interface ProptyDontHaveChildren {
[index: string]: string;
children?: never; // note the ?
}
这保证ProptyDontHaveChildren
只能从缺少或未定义children
属性的东西中创建。
但现在交叉点IntersectionType
将不是你想要的:它也不能有children
因为交集要求children
都是类型undefined
和类型{} ChildrenType
,这是不可能的:
let oops: IntersectionType = { children: [1, 2, 3] } // error
因此,最好的办法是将ProptyDontHaveChildren
定义为基本Propty
类型和WithoutChildren
类型的交集,以便您可以定义ProptyHaveChildren
(您想要的IntersectionType
)作为Propty
和WithChildren
的交集。像这样:
interface Propty {
[index: string]: string;
}
interface WithoutChildren {
children?: never
}
interface WithChildren {
children: ChildrenType
}
type ProptyDontHaveChildren = Propty & WithoutChildren
type ProptyHaveChildren = Propty & WithChildren
但仍有问题。 ProptyHaveChildren
类型仍然不能具有children
类型的属性,因为索引签名要求每个属性包括children
属于{{ 1}}。因此string
必须是children
和string
数组,这是不可能的:
number
从这里我不确定你想怎么做。 TypeScript缺少subtraction types,这就是你需要说索引签名应引用除 const proptyHaveChildren: ProptyHaveChildren = {
a: "a",
children: [1, 2, 3]
}; // error!
function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) {
// error!
const newProps:ProptyHaveChildren = { children: children, ...props }
}
之外的每个string
键。您可以打开"children"
类型,以便每个属性都是Propty
或string
的数组:
number
虽然有效,但现在每个属性都会接受interface Propty {
[index: string]: string | ChildrenType;
}
function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) {
// no error
const newProps:ProptyHaveChildren = { children: children, ...props }
}
:
numbers
这可能不是你想要的。
此时我注意到我正在与TypeScript抗争以迫使它理解你的界面。也许最好的办法是更改const proptyHaveChildren: ProptyHaveChildren = {
a: [1, 2, 3],
children: [1, 2, 3]
}; // no error!
的表示形式,使其包含两个属性:Propty
属性来保存所有props
属性,以及string
:< / p>
children
现在TypeScript理解,一切正常......代价是将你的类型分成多个子属性。您可能更喜欢原始结构。您是否更愿意处理上述问题取决于您。
希望有所帮助。祝你好运!
答案 1 :(得分:1)
您可以使用never
类型来表明children
上不应该存在ProptyDontHaveChildren
:
type ChildrenType = Array<number>
interface ProptyDontHaveChildren {
[index: string]: string;
children: never;
}
interface WithChildren {
children: ChildrenType
}
type IntersectionType = ProptyDontHaveChildren & WithChildren;
function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) {
// OK. No error
const newProps:IntersectionType = { children: children, ...props }
}