React TypeScript错误,除非我传播props

qni6mghb  于 2023-04-22  发布在  TypeScript
关注(0)|答案(1)|浏览(103)

我在下面的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
更新:上面的代码被简化了,但可能不清楚我想实现什么。
我有一个ValCordValStringValNumeric类型的对象数组。我需要将这些对象传递给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>
  );
}
neekobn8

neekobn81#

正如其他人在评论中提到的,当你把type传递给Comp时,type属性的类型是"str1" | "str2" | "num1" | "num2",它太宽了,Typescript抱怨这既不是SMumeric也不是SString。
我的建议是将整个部分作为一个 prop 传递,这样你就不会丢失这些信息:

function Comp({ section }: { section: Section }) {
  return (
    <div style={{marginBottom: 20}}>
      <div>{section.type}</div>
      <div>{section.value.valueLiteral}</div>
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      {state.sections.map((item) => {
        return <Comp key={item.type} section={item} />;
      })}
    </div>
  );
}

相关问题