React 根据 属性 值使用不同的接口
React use different interface in dependent on property value
我有 3 种不同类型的物品,我有它们的接口
interface TypeA{
name: string;
}
interface TypeB{
count: number;
}
interface TypeC{
date: Date;
}
此项目应呈现在项目列表中(在列表中,所有项目都来自同一类型)。根据项目的类型,调用不同的方法,这将呈现不同的布局。
export const ListItem: React.FC<ListItemProps> = (props) => {
let item = null;
switch (props.type) {
case "A":
item = renderTypeA(props);
break;
case "B":
item = renderTypeB(props);
break;
case "C":
item = renderTypeC(props);
break;
}
return item;
};
该方法应该只接受所需类型的项目。
const renderTypeA = (props: TypeAProps) => {
{...}
};
问题是我无法让 Typescript 识别类型的所有属性,也无法自动完成相应的类型。
我也尝试过联合类型“ListItemTypes”,
type ListItemTypes = TypeA | TypeB | TypeC
export const ListItem: React.FC<ListItemTypes> = (props) => {
...
};
但是当我随后尝试包含 ListItem 时,我总是收到缺少属性的错误消息。
<ListItem {...item /> <--- is telling me that properties are missing
有谁知道我该如何解决这个问题?
下面是可区分联合用法的最小示例:
interface TypeA {
type: "A";
name: string;
}
interface TypeB {
type:"B";
count: number;
}
export const ListItem = (props: TypeA | TypeB) => {
let item = null;
switch (props.type) {
case "A":
item = renderTypeA(props); // TS know this must be TypeA in this block
break;
case "B":
item = renderTypeB(props);
break;
}
return item;
};
const renderTypeA = (props: TypeA) => {
props.name; // No error
};
const renderTypeB = (props: TypeB) => {
props.name; // Error
};
// Update:
const renderItem = () => {
const sampleData: Array<ListItemTypes> = [
{
type: "A",
count: 12, // This doesn't follow your ListItemTypes shape
},
];
// ListItem requires an object, not a list of objects
return sampleData.map(sd => <ListItem {...sd} />);
};
我检查了你的代码,它正在抛出错误,因为你正在将一个数组解构到你的组件中。
在你的代码中
const renderItem = () => {
const sampleData = [
{
type: "A",
count: 12,
},
];
// incorrectly destructuring sampleData here
return <ListItem {...sampleData} />;
};
你应该可以用这个来达到预期的结果:
const renderItemA = () => {
const sampleData = {
type: "A" as const, // notice const assertion here
name: "name"
};
return <ListItem {...sampleData} />;
};
因为您将 type
定义为文字类型,所以您需要 const assertion 以便
no literal types in that expression should be widened (e.g. no going from "hello" to string)
我有 3 种不同类型的物品,我有它们的接口
interface TypeA{
name: string;
}
interface TypeB{
count: number;
}
interface TypeC{
date: Date;
}
此项目应呈现在项目列表中(在列表中,所有项目都来自同一类型)。根据项目的类型,调用不同的方法,这将呈现不同的布局。
export const ListItem: React.FC<ListItemProps> = (props) => {
let item = null;
switch (props.type) {
case "A":
item = renderTypeA(props);
break;
case "B":
item = renderTypeB(props);
break;
case "C":
item = renderTypeC(props);
break;
}
return item;
};
该方法应该只接受所需类型的项目。
const renderTypeA = (props: TypeAProps) => {
{...}
};
问题是我无法让 Typescript 识别类型的所有属性,也无法自动完成相应的类型。
我也尝试过联合类型“ListItemTypes”,
type ListItemTypes = TypeA | TypeB | TypeC
export const ListItem: React.FC<ListItemTypes> = (props) => {
...
};
但是当我随后尝试包含 ListItem 时,我总是收到缺少属性的错误消息。
<ListItem {...item /> <--- is telling me that properties are missing
有谁知道我该如何解决这个问题?
下面是可区分联合用法的最小示例:
interface TypeA {
type: "A";
name: string;
}
interface TypeB {
type:"B";
count: number;
}
export const ListItem = (props: TypeA | TypeB) => {
let item = null;
switch (props.type) {
case "A":
item = renderTypeA(props); // TS know this must be TypeA in this block
break;
case "B":
item = renderTypeB(props);
break;
}
return item;
};
const renderTypeA = (props: TypeA) => {
props.name; // No error
};
const renderTypeB = (props: TypeB) => {
props.name; // Error
};
// Update:
const renderItem = () => {
const sampleData: Array<ListItemTypes> = [
{
type: "A",
count: 12, // This doesn't follow your ListItemTypes shape
},
];
// ListItem requires an object, not a list of objects
return sampleData.map(sd => <ListItem {...sd} />);
};
我检查了你的代码,它正在抛出错误,因为你正在将一个数组解构到你的组件中。 在你的代码中
const renderItem = () => {
const sampleData = [
{
type: "A",
count: 12,
},
];
// incorrectly destructuring sampleData here
return <ListItem {...sampleData} />;
};
你应该可以用这个来达到预期的结果:
const renderItemA = () => {
const sampleData = {
type: "A" as const, // notice const assertion here
name: "name"
};
return <ListItem {...sampleData} />;
};
因为您将 type
定义为文字类型,所以您需要 const assertion 以便
no literal types in that expression should be widened (e.g. no going from "hello" to string)