TypeScript如何禁止传入未知字符串字面量但允许动态字符串?
可行,实现方案如下
你可以通过调整泛型约束,限制传入的参数只能是已知的PersonName字面量,或是无法被窄化为具体字面量的动态string类型,从而在编译时拦截已知不存在的字面量名称。
修改后的代码
const ages = { alice: 25, bob: 30, charlie: 35, } type PersonName = keyof typeof ages function getAge<Name extends PersonName | (string extends Name ? string : never)>( name: Name ): Name extends PersonName ? number : number | null { return (ages[name as PersonName] ?? null) as ReturnType<typeof getAge> }
代码说明
泛型约束调整:
Name extends PersonName | (string extends Name ? string : never)是核心逻辑:- 如果
Name是PersonName中的已知字面量(比如'alice'),直接通过约束; - 如果
Name是宽泛的string类型(比如prompt返回的动态字符串),string extends Name为true,允许通过; - 如果
Name是不在PersonName里的具体字面量(比如'frankie'),string extends Name为false,约束结果为never,触发类型检查错误。
- 如果
返回类型优化:
- 保留原有的条件类型逻辑,根据输入类型自动推导返回值:已知名称返回
number,动态字符串返回number | null。
- 保留原有的条件类型逻辑,根据输入类型自动推导返回值:已知名称返回
场景测试
getAge('alice') // ✅ 正常,返回类型`number` getAge('frankie') // ❌ 类型错误:参数类型'"frankie"'不能赋值给类型'PersonName | never' getAge(prompt('Enter your name:') ?? '') // ✅ 正常,返回类型`number | null`
内容的提问来源于stack exchange,提问作者Lionel Rowe
相关产品推荐
相关产品推荐

