TypeScript:基于函数行为自动生成类型及单接口推导输入输出
关于TypeScript类型自动推导的两个问题解答
一、TypeScript能否基于函数行为自动生成/获取简单类型?
首先得明确:TypeScript是静态类型系统,它不会在运行时执行函数来生成类型,但它提供了强大的类型推断能力和一系列高级类型工具,能让你基于函数的类型签名、逻辑结构来推导或生成对应的类型,模拟“基于行为生成类型”的效果。
举几个常见的场景:
- 函数返回值自动推断:如果你写了一个函数,TypeScript会根据函数内部的逻辑自动推断返回值类型,不用手动声明。比如:
function add(a: number, b: number) { return a + b; // 返回值类型自动推断为number } - 用工具类型提取函数相关类型:TypeScript内置了
ReturnType<T>、Parameters<T>等工具类型,能从函数类型中提取返回值、参数列表的类型:type AddFunc = typeof add; type AddReturnType = ReturnType<AddFunc>; // 类型为number type AddParams = Parameters<AddFunc>; // 类型为[number, number] - 条件类型+映射类型模拟行为推导:如果函数有更复杂的逻辑(比如处理对象结构),可以用条件类型、映射类型组合,基于输入类型推导输出类型,这也是你第二个问题的核心解法。
不过要注意:这一切都是在编译时完成的,TypeScript不会运行你的函数代码,而是基于你写的类型注解和代码结构做静态分析。
二、能否仅定义一个接口,自动推导转换函数的输入/输出接口?
完全可以!这里的核心是TypeScript的映射类型,它能让你基于已有类型的键,创建新的类型结构。
场景1:定义输入类型,自动推导输出类型
假设你先定义了输入的接口:
interface FooInput { a: { id: number }; b: { id: number }; c: { id: number }; // 可以扩展更多属性 }
那么输出类型可以直接用映射类型生成,不用手动写第二个接口:
// 遍历FooInput的所有键,将每个属性值替换为原属性的id类型 type FooOutput = { [K in keyof FooInput]: FooInput[K]['id'] }; // FooOutput的结构就是 { a: number; b: number; c: number; }
如果把这个逻辑放到泛型函数里,甚至连输入接口都不用提前定义,TypeScript会自动基于你传入的对象推导类型:
import _ from 'lodash'; function extractIds<T extends Record<string, { id: number }>>(map: T): { [K in keyof T]: T[K]['id'] } { const newMap = {} as { [K in keyof T]: T[K]['id'] }; _.forIn(map, (val, key) => { newMap[key as keyof T] = val.id; }); return newMap; } // 使用示例:传入foo对象,自动推导返回值类型 const foo = { a: { id: 1 }, b: { id: 1 }, c: { id: 1 } }; const bar = extractIds(foo); // bar的类型会被自动推断为 { a: number; b: number; c: number; }
场景2:定义输出类型,反向推导输入类型
如果你先确定了输出的接口,也可以反向推导输入类型:
interface FooOutput { a: number; b: number; c: number; } // 遍历FooOutput的所有键,将每个属性值包装成带id的对象 type FooInput = { [K in keyof FooOutput]: { id: FooOutput[K] } }; // FooInput的结构就是 { a: { id: number }; b: { id: number }; c: { id: number }; }
这样不管是先定义输入还是输出,都只需要写一个接口/类型,另一个就能自动推导出来,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Frame91
相关产品推荐
相关产品推荐

