React TypeScript如何为Props中的空数组触发编译时错误
如何强制TypeScript组件Props中的tabs数组不能为空?
嘿,这个问题我之前也折腾过,TypeScript里要实现数组非空的编译时校验,其实用元组类型就能完美解决,给你一步步讲清楚:
首先先看你的组件代码:
import {Button, Tabs} from 'antd'; import * as React from "react"; import {ReactElement} from "react"; import {IBaseComponentProps} from "../BaseComponent/BaseComponent"; const operations = <Button type={"primary"}>Extra Action</Button>; export interface ITabContent { title: string, content: ReactElement<any> } interface ITabProps extends IBaseComponentProps { tabs: ITabContent[] } export const Tab: React.SFC<ITabProps> = props => { const tabs: any = []; props.tabs.forEach((tab: ITabContent, index: number) => { tabs.push(<Tabs.TabPane tab={tab.title} key={index}>{tab.content} </Tabs.TabPane>) }); return ( <Tabs tabBarExtraContent={operations}> {...tabs} </Tabs> ); };
你想要的是让tabs数组在编译时就不能是空的,之前尝试的& !never[]这种写法确实行不通,TypeScript没有这种语法。下面给你两种最实用的解决方案:
方案1:直接用元组类型约束
TypeScript的元组类型可以定义“至少包含一个元素”的数组,只需要把ITabProps里的tabs类型改成:
interface ITabProps extends IBaseComponentProps { tabs: [ITabContent, ...ITabContent[]]; }
这个写法的意思是:数组必须至少有一个ITabContent类型的元素,后面可以跟着任意多个同类型的元素。
现在如果有人给你的Tab组件传空数组[],TypeScript会直接抛出编译错误,完全达到你要的强制非空效果。
方案2:封装通用的非空数组类型
如果你的项目里很多地方都需要非空数组的类型,可以封装一个通用的NonEmptyArray类型,复用起来更方便:
// 定义通用非空数组类型 type NonEmptyArray<T> = [T, ...T[]]; // 然后在Props里使用 interface ITabProps extends IBaseComponentProps { tabs: NonEmptyArray<ITabContent>; }
为什么不推荐其他方式?
你之前尝试的用never做类型交集的思路走不通,因为TypeScript里没有!这种否定类型的操作符。而用条件类型判断空数组的方式(比如T[] extends [] ? never : T[])其实不太可靠,因为TypeScript无法在编译时准确推断空数组的类型,元组类型是最直接有效的方案。
另外,如果你需要对这个数组做可变操作(比如push、splice),直接用上面的元组类型就可以,不需要加readonly,它和普通数组一样支持所有数组方法。
内容的提问来源于stack exchange,提问作者Sebastien
相关产品推荐
相关产品推荐

