TypeScript条件类型获取可选数组属性数字索引报错求解决
TypeScript可选属性索引生成联合类型问题解决
问题场景
我写了这段TypeScript代码:
type Numbers = [3,65,2,7,3,99,23,555]; interface Options { options?: Numbers; } type FilterOption = Options['options'] extends undefined ? undefined : Options['options'][number];
想要创建一个引用options索引的联合类型,但因为options是可选属性,直接用Options['options'][number]会因为可能为undefined报错。尝试用条件类型判断是否为undefined,甚至加括号禁用分发:
type FilterOption = [Options['options']] extends [undefined] ? undefined : Options['options'][number];
还是报同样的错:
Type 'Numbers | undefined' has no matching index signature for type 'number'
这是不是类型收窄的限制?有没有可行的解决办法?
可行解决方案
方法1:用NonNullable过滤undefined
直接把Options['options']中的undefined排除后再取索引类型:
type FilterOption = Options['options'] extends undefined ? undefined : NonNullable<Options['options']>[number];
也可以用非空断言!直接标记该类型不为undefined:
type FilterOption = Options['options'] extends undefined ? undefined : (Options['options']!)[number];
方法2:用Extract提取有效类型
从Options['options']的联合类型里提取出Numbers类型,再生成联合类型,最后补上undefined:
type FilterOption = Extract<Options['options'], Numbers>[number] | undefined;
方法3:用infer做类型推导
通过infer把Options['options']提取到单独的类型变量中,再做条件判断,这样分支里的类型会被正确收窄:
type FilterOption = Options['options'] extends infer T ? T extends undefined ? undefined : T[number] : never;
问题原因
直接用条件判断没效果,是因为Options['options']本身是Numbers | undefined的联合类型。哪怕禁用了分发,[Numbers | undefined] extends [undefined]不成立,进入else分支后,Options['options']还是保留了联合类型,访问[number]时自然会报错。而上面的方法都是先把undefined从类型里排除,再处理索引操作,就能避免这个问题。
内容的提问来源于stack exchange,提问作者Galivan
相关产品推荐
相关产品推荐

