如何基于数据模型动态构造TypeScript类型安全返回值?
问题
我正在开发一个模块,允许其他开发者创建包含未知属性与限定类型的数据模型(仅支持string、number、boolean类型)。该数据模型为对象,键是属性名,值是包含type字符串与其他配置项的对象。我希望函数基于此数据模型返回具备完整智能提示的类型安全对象。已知可通过泛型让调用方定义类型后返回,但无法直观接收其他配置项。请问能否不使用泛型基于数据模型动态构造类型?或有无巧用泛型的方式,接收此类对象并转换为预期返回类型?
示例代码
//Module function function createDynamicReturnType(datamodel: { [key:string]: { type: 'string'|'number'|'boolean', someOption: boolean } }) : {[key:string]: string|number|boolean } { const typesafeModelObject = {}; //iterate datamodel keys and map the correct type from the type string //'string' -> type string //'number' -> type number //'boolean' -> type boolean //someOption on the properties is used for something but not interesting to return return typesafeModelObject; } //Usage const typesafePerson = createDynamicReturnType({ name: { type: 'string', someOption: true, }, registered: { type: 'boolean', someOption: false, }, age: { type: 'number', someOption: true, }, }); //Wanted result //typesafePerson has correct types and Intellisense //typesafePerson.name -> string //typesafePerson.registered -> boolean //typesafePerson.age -> number
解决方案
TypeScript的静态类型系统无法脱离泛型实现基于运行时输入的动态类型推导,但我们可以通过泛型结合映射类型与条件类型,让函数自动根据传入的数据模型推导出精确的返回类型,同时完整支持配置项的传递。
具体实现
首先定义一个类型映射表,将字符串类型标识对应到TypeScript的内置基础类型:
type TypeMap = { string: string; number: number; boolean: boolean; };
接着改造函数,通过泛型捕获传入数据模型的具体结构,再用映射类型推导返回类型:
function createDynamicReturnType<T extends Record<string, { type: keyof TypeMap; someOption: boolean }>>( datamodel: T ): { [K in keyof T]: TypeMap[T[K]['type']] } { const typesafeModelObject = {} as { [K in keyof T]: TypeMap[T[K]['type']] }; // 根据数据模型的type字段初始化对应类型的属性值 for (const key in datamodel) { const { type } = datamodel[key]; // 可根据需求设置默认值,示例使用基础类型默认值 switch (type) { case 'string': typesafeModelObject[key] = ''; break; case 'number': typesafeModelObject[key] = 0; break; case 'boolean': typesafeModelObject[key] = false; break; } } return typesafeModelObject; }
使用效果
调用函数时传入数据模型,TypeScript会自动推导返回对象的精确类型:
const typesafePerson = createDynamicReturnType({ name: { type: 'string', someOption: true }, registered: { type: 'boolean', someOption: false }, age: { type: 'number', someOption: true }, }); // 此时能获得完整的智能提示: // typesafePerson.name → string // typesafePerson.registered → boolean // typesafePerson.age → number
原理说明
- 泛型
T会精准捕获调用时传入的数据模型的结构,包括所有属性名和对应的type字段值 - 映射类型
{ [K in keyof T]: TypeMap[T[K]['type']] }遍历T的每个属性,将type字符串映射为对应的基础类型 - 函数内部通过类型断言让TypeScript识别返回值的精确类型,确保类型安全
这样既保留了接收someOption等配置项的能力,又实现了带智能提示的类型安全返回值。
内容的提问来源于stack exchange,提问作者nidaros
相关产品推荐
相关产品推荐

