是否可以使用带有枚举的对象字面量来返回 Typescript/React 中的不同组件?
如果没有,为什么这个模式不起作用?
enum ItemType {
TASK,
NOTE,
}
function NoteComponent(props: { type: ItemType.NOTE }) {
return <div />;
}
function TaskComponent(props: { type: ItemType.TASK }) {
return <div />;
}
function getComp(type: ItemType): typeof NoteComponent | typeof TaskComponent {
return {
[ItemType.NOTE]: NoteComponent,
[ItemType.TASK]: TaskComponent,
}[type];
}
const noteProps = { type: ItemType.NOTE };
const taskProps = { type: ItemType.TASK };
function App() {
const Comp1 = getComp(noteProps.type);
const Comp2 = getComp(taskProps.type);
return (
<>
<Comp1 {...noteProps} />
{/**
Type '{ type: ItemType; }' is not assignable to type 'never'.
The intersection 'IntrinsicAttributes & { type: ItemType.NOTE; }
& { type: ItemType.TASK; }' was reduced to 'never' because
property 'type' has conflicting types in some constituents.
ts(2322)
*/}
<Comp2 {...taskProps} />
{/**
Type '{ type: ItemType; }' is not assignable to type 'never'.
The intersection 'IntrinsicAttributes & { type: ItemType.NOTE; }
& { type: ItemType.TASK; }' was reduced to 'never' because
property 'type' has conflicting types in some constituents.
ts(2322)
*/}
</>
);
}
更新:
当值是从 API 返回而不是硬编码时,您如何设置 ItemType.NOTE as const
?
const apiResponse = [
{ type: ItemType.NOTE, ...noteSpecificProps },
{ type: ItemType.TASK ...taskSpecificProps },
];
apiResponse.map(item => {
const Comp = getComp(noteProps.type);
return <Comp {...item} />;
});
答案 0 :(得分:2)
getComp
函数应该根据提供的类型(而不是联合)返回特定的组件。这可以通过重载或泛型来实现。{ type: ItemType.NOTE }
中,type
被扩展为 ItemType
,以防止可以使用此 as const
assertion。const componentMap = {
[ItemType.NOTE]: NoteComponent,
[ItemType.TASK]: TaskComponent,
}
function getComp<T extends ItemType>(type: T) {
return componentMap[type];
}
const noteProps = { type: ItemType.NOTE } as const;
const taskProps = { type: ItemType.TASK } as const;
function App() {
const Comp1 = getComp(noteProps.type);
const Comp2 = getComp(taskProps.type);
return (
<>
<Comp1 {...noteProps} />
<Comp2 {...taskProps} />
</>
);
}