这里有相当多的问题。警告:
你可以做children
never
型或ProptyDontHaveChildren
undefined
的可选属性(该属性是可选很重要):
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
都是string
类型。所以children
必须是一个string
和number
阵列,这是不可能发生的:
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 }
}
在这里,我不知道你怎么想继续。 TypeScript缺少,这就是你需要说的索引签名应该指的是每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
数组:
const proptyHaveChildren: ProptyHaveChildren = {
a: [1, 2, 3],
children: [1, 2, 3]
}; // no error!
这可能不是你想要的。
在这一点上,我注意到我正在与TypeScript战斗,迫使它理解你的界面。也许做的最好的事情是改变你的Propty
表示,使得它包含两个属性:一个props
属性来保存所有这些string
属性,children
:
type ChildrenType = Array<number>
interface Propty {
props: { [index: string]: string }
}
interface WithoutChildren {
children?: never
}
interface WithChildren {
children: ChildrenType
}
type ProptyDontHaveChildren = Propty & WithoutChildren
type ProptyHaveChildren = Propty & WithChildren
const proptyHaveChildren: ProptyHaveChildren = { props: { a: "a" }, children: [1, 2, 3] }; // works
function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) {
const newProps: ProptyHaveChildren = { children: children, props: props.props } // works
}
现在打字稿了解到,和一切正常...代价是将你的类型分成多个子属性。你可能更喜欢你的原始结构。无论您是否愿意处理上述问题,都取决于您。
希望有所帮助。祝你好运!
不能;如何在创建newProps之前删除道具['children'],甚至是简单的:'newProps = {...道具}; newProps.children =儿童'? –