如何从字符串获取TypeScript类型名?泛型函数类型报错排查
问题根源
TypeScript 默认会将对象字面量中的字符串值拓宽为 string 类型,而非保留精确的字面量类型(比如 'string')。这导致 config.properties 里每个属性的 type 被推断为 string,无法匹配我们定义的 PropertyType('string' | 'number' | 'boolean' | 'object'),进而触发类型不兼容错误。
解决方案
步骤1:用as const保留字面量类型
添加 as const 断言,强制 TypeScript 保留每个 type 字段的精确字面量类型,避免自动拓宽:
const config = { namespace: 'foo', properties: { foo: { type: 'string' }, bar: { type: 'number', fallback: 1338 }, baz: { type: 'boolean', nullable: true }, complicatedThing: { type: 'object', nullable: true, fallback: () => ({ foo: 'bar', bar: 'baz', arr: [1,2], }) } } } as const;
步骤2:优化泛型函数的类型推断
重写 getFallback 函数,让它能根据传入的属性自动推断 fallback 的返回类型:
// 工具类型:提取fallback的实际返回值类型 type FallbackReturnType<T> = T extends (...args: any[]) => infer R ? R : T extends null | undefined ? T : T; function getFallback< TProps extends Record<string, { type: PropertyType; nullable?: boolean; fallback?: any }> >(props: TProps) { return <K extends keyof TProps>(key: K): FallbackReturnType<TProps[K]['fallback']> => { const fallback = props[key].fallback; return typeof fallback === 'function' ? fallback() : fallback; }; }
步骤3:调用优化后的函数
现在 TypeScript 能正确推断每个属性的返回类型:
// 创建针对当前config的fallback获取函数 const getConfigFallback = getFallback(config.properties); // 正确推断类型:{ foo: string; bar: string; arr: number[]; } const foo = getConfigFallback('complicatedThing'); // 其他属性的类型也会自动匹配 const bar = getConfigFallback('bar'); // number const baz = getConfigFallback('baz'); // boolean | null | undefined
可选:增强类型约束(进阶)
如果需要更强的结构约束,可以将 StorageConfig 改为泛型,确保配置严格符合定义:
type StorageConfig<T extends Record<string, PropertyDefinition<any, any>>> = { namespace: string, properties: T }; // 显式指定config类型,进一步强化约束 const config: StorageConfig<typeof config.properties> = { // 原config内容... } as const;
内容的提问来源于stack exchange,提问作者foo
相关产品推荐
相关产品推荐

