无需使用`as const`,如何推导函数参数的字符串字面量类型?
无需
as const推导React组件keys字面量类型的方法 你当前的Pager组件通过as const来让TypeScript推导keys的字面量类型,其实有两种方法可以省去这个额外的断言:
方法一:调整泛型约束为只读字面量数组
通过将泛型约束直接指定为readonly [string, string, ...string[]],TypeScript会自动对传入的数组字面量推导为对应的字面量类型数组,无需as const。
修改后的组件代码:
import React, { useState } from 'react'; interface PagerProps<Keys extends readonly [string, string, ...string[]]> { children: (props: { currentKey: Keys[number] }) => React.ReactNode; keys: Keys; } function Pager<Keys extends readonly [string, string, ...string[]]>({ children, keys }: PagerProps<Keys>) { const [currentKey, setCurrentKey] = useState<Keys[number]>(keys[0]); return children({ currentKey }); }
使用示例:
<Pager keys={['a', 'b']}> {({ currentKey }) => { if (currentKey === 'a') {} if (currentKey === 'lalala') {} // 此处会抛出类型错误,符合预期 return <div>当前key: {currentKey}</div>; }} </Pager>
原理:当React组件的props接收一个数组字面量,且泛型约束要求该数组为只读类型时,TypeScript会自动保留数组元素的字面量类型,不会将其拓宽为string类型。
方法二:使用TypeScript 5.0+的const泛型
如果你的项目使用TypeScript 5.0及以上版本,可以利用const泛型特性,强制TypeScript推导精确的字面量类型,代码更简洁:
修改后的组件代码:
import React, { useState } from 'react'; interface PagerProps<Keys extends readonly string[]> { children: (props: { currentKey: Keys[number] }) => React.ReactNode; keys: Keys; } function Pager<const Keys extends readonly [string, string, ...string[]]>({ children, keys }: PagerProps<Keys>) { const [currentKey, setCurrentKey] = useState<Keys[number]>(keys[0]); return children({ currentKey }); }
使用方式和上面一致,传入keys={['a', 'b']}时,TypeScript会自动推导Keys为readonly ["a", "b"],currentKey的类型也会被限制为"a" | "b"。
原理:const泛型会告诉TypeScript不要对传入的字面量类型进行拓宽,直接保留其精确的字面量值类型,因此不需要额外的as const断言。
内容的提问来源于stack exchange,提问作者AKG
相关产品推荐
相关产品推荐

