TypeScript:如何让数组项根据name属性自动推断泛型类型
如何让TypeScript根据导航栈元素的name自动推断对应泛型类型?
我有如下动态导航栈数组:
const fullKYCStack = [ { name: 'Account Credentials Screen', component: AccountCredentialsScreen, }, { name: 'Verify Email Screen', component: VerifyEmailScreen, }, // 更多元素... ];
同时存在定义导航名称的类型:
type KYCStackParamList = { 'Account Credentials Screen': undefined; 'Verify Email Screen': undefined; // 更多键值对... };
我希望数组中每个元素的component的props类型与name属性对应的KYCStackParamList键匹配,例如第一个元素的类型应该是:
type AccountCredentialsScreenItem = { name: 'Account Credentials Screen'; component: ( props: NativeStackScreenProps<KYCStackParamList, 'Account Credentials Screen'>, ) => JSX.Element; };
我尝试定义了泛型接口:
interface KYCScreen<K extends keyof KYCStackParamList> { name: K; component: ( props: NativeStackScreenProps<KYCStackParamList, K>, ) => JSX.Element; }
但把这个接口应用到数组时,泛型无法自动推断,报错:Generic type 'KYCScreen' requires 1 type argument(s).ts(2314)。请问怎么让TypeScript根据每个元素的name属性自动获取对应的泛型类型值?
解决方案
核心思路是创建一个联合类型覆盖KYCStackParamList的所有键,让数组类型基于这个联合类型,TypeScript就能自动为每个元素匹配对应类型。
1. 生成屏幕类型联合
通过映射类型遍历KYCStackParamList的所有键,生成对应的屏幕类型,再组合成联合类型:
type KYCScreen = { [K in keyof KYCStackParamList]: { name: K; component: (props: NativeStackScreenProps<KYCStackParamList, K>) => JSX.Element; }; }[keyof KYCStackParamList];
这段代码会为KYCStackParamList中的每个键K生成专属的屏幕类型,最后通过[keyof KYCStackParamList]提取所有类型组成联合。
2. 指定数组类型
直接将fullKYCStack的类型设置为KYCScreen[]:
const fullKYCStack: KYCScreen[] = [ { name: 'Account Credentials Screen', component: AccountCredentialsScreen, }, { name: 'Verify Email Screen', component: VerifyEmailScreen, }, // 更多元素... ];
此时TypeScript会自动做以下检查:
- 每个元素的
name必须是KYCStackParamList中的有效键 - 对应
component的props类型必须与name匹配,比如name为'Account Credentials Screen'时,component必须接受NativeStackScreenProps<KYCStackParamList, 'Account Credentials Screen'>类型的参数 - 若类型不匹配,会直接抛出类型错误
为什么之前的泛型接口无效?
之前的泛型接口KYCScreen<K>需要显式指定泛型参数,而数组无法自动为每个元素推断不同的K值。联合类型则预先生成了所有可能的合法类型组合,数组中的每个元素只需匹配联合中的某一项即可,TypeScript会自动完成类型推断。
内容的提问来源于stack exchange,提问作者nanobar
相关产品推荐
相关产品推荐

