我在下面的React代码中得到了一个TypeScript错误,除非我传播了props。为什么会发生这种情况?
interface SString {
type: "str1" | "str2";
value: { valueLiteral: string };
}
interface SNumeric {
type: "num1" | "num2";
value: { valueLiteral: number };
}
type Section = SString | SNumeric;
interface State {
sections: Section[];
}
const state: State = {
sections: [
{ type: "str1", value: { valueLiteral: "val1" } },
{ type: "num1", value: { valueLiteral: 1 } }
]
};
function Comp({ type, value }: Section) {
return (
<div style={{marginBottom: 20}}>
<div>{type}</div>
<div>{value.valueLiteral}</div>
</div>
);
}
export default function App() {
return (
<div className="App">
{state.sections.map((item) => {
// return <Comp key={item.type} {...item} />; // This doesnt error
return <Comp key={item.type} type={item.type} value={item.value} />;
})}
</div>
);
}
function Comp({ type,value }:节):JSX.元素类型'{键:“str1”|“str2”|“num1”|“num2”; type:“str1”|“str2”|“num1”|“num2”; value:{ valueLiteral:string; }|{ valueLiteral:number; }; }'不能分配给类型'IntrinsicAttributes & Section '。Type '{ key:“str1”|“str2”|“num1”|“num2”; type:“str1”|“str2”|“num1”|“num2”; value:{ valueLiteral:string; }|{ valueLiteral:“number; }; }”不能分配给类型“SNumeric”。属性“type”的类型不兼容。类型“str 1”|“str2”|“num1”|“num 2”"不可分配给类型““num 1””|“num 2”“。类型”“str 1”"不可分配给类型““num 1””|“num2”'. ts(2322)
Blockquote
更新:上面的代码被简化了,但可能不清楚我想实现什么。
我有一个ValCord
,ValString
和ValNumeric
类型的对象数组。我需要将这些对象传递给React组件,并让该组件根据对象类型调用其他组件。
https://codesandbox.io/s/fast-sunset-8egckr?file=/src/App.tsx:0-1594
interface ValCord {
type: "padding" | "margin";
value: { x: number; y: number };
}
interface ValString {
type: "color" | "font";
value: string;
}
interface ValNumeric {
type: "font-size" | "font-weight";
value: number;
}
type Val = ValCord | ValString | ValNumeric;
interface State {
sections: Val[];
}
const val1: ValCord = {
type: "padding",
value: {
y: 8,
x: 10
}
};
const val2: ValString = {
type: "color",
value: "white"
};
const val3: ValNumeric = {
type: "font-size",
value: 12
};
const state: State = {
sections: [val1, val2, val3]
};
function ValCordComp({ type, value }: ValCord) {
return (
<div>
{type} - X:{value.x} Y:{value.y}
</div>
);
}
function ValStringComp({ type, value }: ValString) {
return (
<div>
{type} is {value.toUpperCase()}
</div>
);
}
function ValNumericComp({ type, value }: ValNumeric) {
return (
<div>
{type} is {value * 100}
</div>
);
}
function Comp({ type, value }: Val) {
return (
<div style={{ marginBottom: 20 }}>
{type === "padding" ? <ValCordComp type={type} value={value} /> : null}
{type === "color" ? <ValStringComp type={type} value={value} /> : null}
{type === "font-size" ? (
<ValNumericComp type={type} value={value} />
) : null}
</div>
);
}
export default function App() {
return (
<div className="App">
{state.sections.map((item) => {
// return <Comp key={item.type} {...item} />;
return <Comp key={item.type} type={item.type} value={item.value} />;
})}
</div>
);
}
1条答案
按热度按时间neekobn81#
正如其他人在评论中提到的,当你把
type
传递给Comp
时,type
属性的类型是"str1" | "str2" | "num1" | "num2"
,它太宽了,Typescript抱怨这既不是SMumeric也不是SString。我的建议是将整个部分作为一个 prop 传递,这样你就不会丢失这些信息: