我有一些typescript
这样的定义:
interface T1 {
children: string[];
}
interface T2 {
children?: number | boolean | undefined | null;
}
type All = T1 & T2;
const b: All = {
children: ['test'],
};
我想知道All[‘children’]
属性到底是什么类型?
我无法为其分配string array
,也不知道如何使用此intersection type
。
在现实生活中,React.js
在children
上有一个React.Component
定义,当我定义自己的children
类型时,在这种情况下没有错误。
更新,在React Native
代码中添加一些真实的代码。我有以下定义:
interface Props {
children: View[];
}
export default Demo extends React.Component<Props> {
}
// later in parent component
<Demo>
<View></View>
<View></View>
</Demo>
我不知道为什么typescript
可以处理children
的{{1}}。这是Demo
children
定义
React.Component
因此,我认为{
children?: ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
}
中type
的最后children
应该是:
Demo
如何将children: (View[] & ReactChild) | (View[] & ReactFragment) | (View[] & ReactPortal) | (View[] & boolean) | (View[] & null) | (View[] & undefined)
传递给View arrays
作为孩子。
再次更新,我发现Demo
的定义是关键。
ReactFragment
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
中的 {}
,结果为ReactFragment
,相当于View[] & {}
答案 0 :(得分:0)
交叉点类型意味着可分配给该类型的实例必须可分配给交叉点的组成部分。这将导致编译器将children
键入为string[] & (number | boolean | undefined | null)
,这是一种很难实现的类型,可能无论如何都不是您想要的。
如果您希望All
是T1
或T2
,则必须使用并集:
interface T1 {
children: string[];
}
interface T2 {
children?: number | boolean | undefined | null;
}
type All = T1 | T2;
const b: All = { // OK
children: ['test'],
};
或者,如果您需要更复杂的合并逻辑,请提供更多详细信息。
答案 1 :(得分:0)
当我阅读React.ReactNode
定义时,我错过了这一点。定义如下:
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
// children definition in React.Component, I’ve deleted other property definition
class Component<P, S> {
// React.Props<T> is now deprecated, which means that the `children`
// property is not available on `P` by default, even though you can
// always pass children as variadic arguments to `createElement`.
// In the future, if we can define its call signature conditionally
// on the existence of `children` in `P`, then we should remove this.
readonly props: Readonly<P> & Readonly<{ children?: ReactNode }>;
}
// my custom component Props definition
interface Props {
children: View[];
}
因此,我的组件的children
定义是:
type C = View[] & ReactNode;
// which is equivalent to this C2
type C2 = (View[] & ReactChild) | (View[] & ReactFragment) | (View[] & ReactPortal) | (View[] & boolean) | (View[] & null) | (View[] & undefined);
如果我们更深入地展开ReactFragment
,我们的类型就是这个
type C3 = (View[] & ReactChild) | (View[] & {}) | (View[] & ReactNodeArray) | (View[] & ReactPortal) | (View[] & boolean) | (View[] & null) | (View[] & undefined);
以及View[] & {}
的结果是什么。我在typescript playground中编写了一个简单的演示。
// Test is equivalent to View[]
type Test = View[] & {};