typescript 如何强制提供给React prop 的字符串为特定类型

pbgvytdp  于 2023-01-21  发布在  TypeScript
关注(0)|答案(3)|浏览(201)

我想提供一个字符串给一个react组件中的prop,这个prop来自一个库,但是即使这个库接受任何字符串,我也想确保我提供的字符串是某种类型的,如果不是,我希望typescript提供一个类型错误。
我喜欢下面这样的东西,但 typescript 会失败。

import React from "react";

// Can't modify this component or props
const ComponentFromLibrary: React.FC<{ str: string }> = ({ str }) => (
  <span>{str}</span>
);

// -----

type AllowedStrings = 'Hello'|'World'
export default () => (
  <div className="App">
    {/* This should not fail */}
    <ComponentFromLibrary str={"Hello" as AllowedStrings} />
    {/* This should fail */}
    <ComponentFromLibrary str={"world" as AllowedStrings} />
  </div>
);

example on codesandbox.io

6bc51xsx

6bc51xsx1#

将库组件 Package 在您自己的检查类型的组件中。

import React, {FC} from "react";

type AllowedStrings = 'Hello'|'World'

type Props = {
    str: AllowedStrings;
}
const ComponentFromLibraryWrapper:FC<Props> = ({str}) => <ComponentFromLibrary str={str} />

export default () => (
  <div className="App">
    {/* This should not fail */}
    <ComponentFromLibraryWrapper str="Hello" />
    {/* This should fail */}
    <ComponentFromLibraryWrapper str="world" />
  </div>
);
yhxst69z

yhxst69z2#

我认为typescript编译器不工作是因为向下转换。类型AllowedStrings与类型string重叠。这意味着向下转换正在工作,并且编译器理解"world"具有类型AllowedStrings。所以使用 Package 器组件是一个可以选择的解决方案。

import React from "react";

type AllowedStrings = "Hello" | "World";

const ComponentFromLibrary: React.FC<{ str: string }> = ({ str }) => {
  return <span>{str}</span>;
};

// Can't modify this component or props
const WrapperCompnent: React.FC<{ str: AllowedStrings }> = ({ str }) => (
  <ComponentFromLibrary str={str} />
);

// -----

export default () => (
  <div className="App">
    {/* This should not fail */}
    <WrapperCompnent str={"Hello"} />
    {/* This should fail */}
    <WrapperCompnent str={"world"} />
  </div>
);
zynd9foi

zynd9foi3#

也许您可以尝试使用TS enum

enum AllowedStrings {
    Hello = "Hello",
    World = "World"
}

{/* Both works */}
<ComponentFromLibrary str={ AllowedStrings[ "Hello" ] } />
<ComponentFromLibrary str={ AllowedStrings[ "World" ] } />

{/* Both will throw error */}
{/* You can't use anything else instead those inside the enum */}
<ComponentFromLibrary str={ AllowedStrings[ "world" ] } />
<ComponentFromLibrary str={ AllowedStrings[ "anything else" ] } />

下面是一个codesandbox示例
希望这有帮助:)

相关问题