TypeScript中如何将对象泛型key从一个类型传递到另一个类型
类型定义解决方案
你可以通过泛型绑定表单字段、转换函数、API字段三者的类型关系,实现全链路类型安全,具体定义方式如下:
1. 基础通用类型定义
先定义转换器泛型,保留你原有的业务类型:
// 转换器泛型:入参是表单字段值,出参是转换后的值,默认不转换时出入参类型一致 type Transformer<InputType, OutputType = InputType> = (value: InputType) => OutputType // 你原有的业务类型 type FormType = { foo: string, bar: string } type ApiRequestType = { example: string, another_example: string }
2. 定义GetFormValueType
通过两层泛型绑定字段类型和转换后的返回类型:
type GetFormValueType = <T extends keyof FormType, R = FormType[T]>( fieldName: T, transformer?: Transformer<FormType[T], R> ) => (form: FormType) => R // 对应实现的类型会自动推导,不需要额外写类型标注 const getFormValue: GetFormValueType = (fieldName, transformer) => form => { const fieldValue = form[fieldName] return transformer ? transformer(fieldValue) : fieldValue }
3. 定义映射相关类型
如果你需要单独抽离ValueType公共类型,可以这么定义:
type ValueType = (form: FormType) => ApiRequestType[keyof ApiRequestType]
更推荐用映射类型替代Record定义映射表,可实现单字段级的类型校验,比通用ValueType更安全:
// 映射表类型:每个API字段对应一个接收表单返回对应字段值的处理函数 type FormToApiMap = { [K in keyof ApiRequestType]: (form: FormType) => ApiRequestType[K] } // 示例transform函数 const transform = (val: string) => val.toUpperCase() // 定义映射表,类型不匹配会直接报错 const FORM_TO_API_REQUEST_MAP: FormToApiMap = { example: getFormValue('foo', transform), another_example: getFormValue('bar', transform) }
4. 完整调用示例
const formData: FormType = { foo: 'hello', bar: 'world' } // 对Object.entries加类型断言解决默认返回string类型key的问题 const apiRequest: ApiRequestType = (Object.entries(FORM_TO_API_REQUEST_MAP) as [keyof ApiRequestType, (form: FormType) => any][]) .reduce((request, [apiRequestKey, handler]) => ({ ...request, [apiRequestKey]: handler(formData) }), {} as ApiRequestType)
以上定义完成后所有环节都是类型安全的:
- 调用
getFormValue时只能传FormType存在的key,传错直接报错 - 转换器的入参类型会自动匹配对应表单字段的类型
- 映射表中每个处理函数的返回值必须和
ApiRequestType对应字段的类型一致,不匹配会直接提示错误 - 最终生成的
apiRequest类型完全匹配ApiRequestType
内容的提问来源于stack exchange,提问作者user16412874
相关产品推荐
相关产品推荐

