這裏有相當多的問題。警告:
你可以做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 =兒童'? –