【发布时间】:2019-04-29 14:21:06
【问题描述】:
我正在努力将我们的 React/redux 项目转换为 TypeScript,并且遇到了 TypeScript 文字类型联合类型的问题。
问题来了:
我用 type 属性(一个字符串)实例化一个 Wrapper 组件:
//index.tsx
import * as React from "react";
import { render } from "react-dom";
import "./styles.css";
import Wrapper from "./wrapper";
function App() {
return <Wrapper type="password" />;
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
我在这个 Wrapper 组件中定义了一个字符串 type 值的“列表”应该适合。为此,我使用 TypeScript Union 类型:type: "value1" | value2 | ...
//Wrapper.tsx
import * as React from "react";
import Input from "./input";
import Select from "./select";
interface ILabeledInput {
type: "textarea" | "password" | "select" | "search" | "email" | "text";
}
export default function Wrapper(props: ILabeledInput) {
switch (props.type) {
case "select":
return <Select {...props} />;
case "password":
return <Input {...props} />;
}
}
这里我使用一个开关来实例化适当的子组件,而不管我在 index.tsx
中定义的类型在子组件中,我也使用 typescript 接口来定义 type 属性类型。 使用此开关:
-type的类型可能只是一个字符串(只有一种可能性):
// select.tsx
import * as React from "react";
interface ISelect {
type: "select";
}
export default function Input(props: ISelect) {
return <p>{props.type}</p>; // fake code, juste to display something
}
-或者再次是 TypeScript Union 类型的字符串(但可能性比原始字符串小):
// input.tsx
import * as React from "react";
interface IInput {
type: "password" | "search" | "email" | "text";
}
export default function Input(props: IInput) {
return <p>{props.type}</p>; // fake code, juste to display something
}
type 的类型从 wrapper 更改为 select/input 组件会产生 TypeScript 错误:
Type '{ type: "textarea" | "password" | "select" | "search" | "email" | "text"; }' is not assignable to type 'ISelect'.
Types of property 'type' are incompatible.
Type '"textarea" | "password" | "select" | "search" | "email" | "text"' is not assignable to type '"select"'.
Type '"textarea"' is not assignable to type '"select"'.ts(2322)
和
Type '{ type: "textarea" | "password" | "select" | "search" | "email" | "text"; }' is not assignable to type 'IInput'.
Types of property 'type' are incompatible.
Type '"textarea" | "password" | "select" | "search" | "email" | "text"' is not assignable to type '"password" | "search" | "email" | "text"'.
Type '"textarea"' is not assignable to type '"password" | "search" | "email" | "text"'.ts(2322)
我知道 Typescript 检测到道具类型的变化,但我找不到如何让它考虑 Switch 条件。
提前感谢您的帮助!!
【问题讨论】:
标签: javascript reactjs typescript