Reactjs TypeScript中的联合类型道具&;反应
我有一个带有道具的组件,我想将其限制在字符串的选择范围内,因此我使用联合类型,如下所示:Reactjs TypeScript中的联合类型道具&;反应,reactjs,typescript,Reactjs,Typescript,我有一个带有道具的组件,我想将其限制在字符串的选择范围内,因此我使用联合类型,如下所示: 类型HeadingProps={ 级别?:“h1”|“h2”|“h3”|“h4”|“h5”|“h6” } 常量标题:React.FC=({子级,级别='h2'})=>{ 返回 } 当我这样使用它时,它很好用 你好,世界! 但如果我尝试将其与数组一起使用,则会出现错误: {['h1',h2',h3',h4',h5',h6'].map((级别:string)=>( {level} )} 类型“string
类型HeadingProps={
级别?:“h1”|“h2”|“h3”|“h4”|“h5”|“h6”
}
常量标题:React.FC=({子级,级别='h2'})=>{
返回
}
当我这样使用它时,它很好用
你好,世界!
但如果我尝试将其与数组一起使用,则会出现错误:
{['h1',h2',h3',h4',h5',h6'].map((级别:string)=>(
{level}
)}
类型“string”不可分配给类型“h1”|“h2”|“h3”|“h4”|“h5”|“h6”|未定义”。ts(2322)
我如何拥有道具的类型,以便只有这些字符串是有效的,但当组件在上面这样的数组中使用时,允许传递有效的字符串值
编辑
以下是类型当前的工作方式:
export const HeadingLevels={
h1:`h1`,
h2:`h2`,
h3:`h3`,
h4:`h4`,
h5:`h5`,
h6:`h6`,
}
导出类型级别=标题级别类型的键
类型HeadingProps=BoxProps&{
级别?:级别
}
['h1',h2',h3',h4',h5',h6']
被编译器推断为类型字符串[]
,因为这通常是正确的操作,如
const arr = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; // inferred as string[]
arr.push("h7"); // okay
但是在您的例子中,您希望编译器知道该数组的内容是并且将永远是(只要您使用它),您设置的特定内容
从TypeScript 3.4开始,处理此问题的最简单方法是使用a来告诉编译器您的数组是用来读取特定字符串文字的:
(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const).map((level) => (
<Heading level={level}>{level}</Heading>
))
(['h1','h2','h3','h4','h5','h6']作为常量)。映射((级别)=>(
{level}
))
这应该可以正常工作。请注意,我已从级别
中删除了类型注释。您不希望将级别
扩展到字符串
,因为这样编译器就不能再确定它是否合适了。相反,让编译器推断级别
的类型,它将根据您的联合h1”|“h2”执行此操作|…|“h6”
,根据需要
好吧,希望能有帮助,祝你好运
['h1',h2',h3',h4',h5',h6']
被编译器推断为类型字符串[]
,因为这通常是正确的操作,如
const arr = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; // inferred as string[]
arr.push("h7"); // okay
但是在您的例子中,您希望编译器知道该数组的内容是并且将永远是(只要您使用它),您设置的特定内容
从TypeScript 3.4开始,处理此问题的最简单方法是使用a来告诉编译器您的数组是用来读取特定字符串文字的:
(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const).map((level) => (
<Heading level={level}>{level}</Heading>
))
(['h1','h2','h3','h4','h5','h6']作为常量)。映射((级别)=>(
{level}
))
这应该可以正常工作。请注意,我已从级别
中删除了类型注释。您不希望将级别
扩展到字符串
,因为这样编译器就不能再确定它是否合适了。相反,让编译器推断级别
的类型,它将根据您的联合h1”|“h2”执行此操作|…|“h6”
,根据需要
好吧,希望能有帮助,祝你好运
如果拆分这些类型,可以使用union type(级别)注释映射函数的
level
参数,如下所示:
type Level = 'h1' | 'h2' | 'h3' | 'h4'| 'h5' | 'h6'
type HeadingProps = {
level?: Level
}
const Heading: React.FC<HeadingProps> = ({children, level = 'h2'}) => {
return <Box as={level} />
}
{['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].map((level: Level) => (
<Heading level={level}>{level}</Heading>
))}
类型级别='h1'|'h2'|'h3'|'h4'|'h5'|'h6'
类型HeadingProps={
级别?:级别
}
常量标题:React.FC=({子级,级别='h2'})=>{
返回
}
{['h1','h2','h3','h4','h5','h6'].map((级别:级别)=>(
{level}
))}
如果拆分这些类型,可以使用union type(级别)注释映射函数的level
参数,如下所示:
type Level = 'h1' | 'h2' | 'h3' | 'h4'| 'h5' | 'h6'
type HeadingProps = {
level?: Level
}
const Heading: React.FC<HeadingProps> = ({children, level = 'h2'}) => {
return <Box as={level} />
}
{['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].map((level: Level) => (
<Heading level={level}>{level}</Heading>
))}
类型级别='h1'|'h2'|'h3'|'h4'|'h5'|'h6'
类型HeadingProps={
级别?:级别
}
常量标题:React.FC=({子级,级别='h2'})=>{
返回
}
{['h1','h2','h3','h4','h5','h6'].map((级别:级别)=>(
{level}
))}
如果将level:string
替换为level:HeadingProps.level
,会发生什么?如果将level:string
替换为level:HeadingProps.level
,会发生什么?啊,太棒了,是的。我已经尝试过了,但没有从level
删除类型注释。非常感谢@jcalz:+1:ah fantastic、 是的,这很有效。我试过了,但没有从级别
删除类型注释。非常感谢@jcalz:+1:是的,我以前有过,但我不希望使用组件的代码必须导入级别
类型,只是为了在组件中传递字符串。当然,对于字符串和数字之类的原语at可能不是必需的。但是,请记住,如果您偶然发现更复杂的联合(如其他类型的联合),as const
不会起作用。是的,我以前有过这种情况,但我不希望使用组件的代码必须导入级别
类型才能在组件中传递字符串。当然,对于可能不需要的字符串和数字等基本体。但是,请记住,如果您偶然发现mor复杂的并集(像其他类型的并集一样),as const
在这里不会起作用。