如何通过传入接口属性名推导对应属性的类型?
解决方法
问题出在泛型参数K设置了默认值keyof T,当你显式指定T时,K会被默认设为keyof T(也就是所有键的联合类型),导致返回的field类型变成T[keyof T](所有值类型的联合)。
只需要去掉K的默认值,让TypeScript根据传入的fieldName自动推断具体的键类型即可:
export const getField = <T extends Record<string, any>, K extends keyof T>(fieldName: K) => { const record = injectRecord<T>(); // sideEffect return { field: record[fieldName] }; }; // in real life here will be different objects const injectRecord = <T>() => ({ number: 123, bool: true, string: 'asd' } as T); // typeof field = boolean const { field } = getField<{ number: number; string: string; bool: boolean }>('bool');
原理说明
- 去掉
K extends keyof T = keyof T中的默认值后,当你传入具体的属性名(比如'bool'),TypeScript会自动将K推断为该具体键类型,而不是所有键的联合类型。 - 此时
record[fieldName]的类型会被准确解析为T[K],也就是对应属性的具体类型(这里就是boolean)。
如果希望更严格的类型约束,可以调整泛型顺序,让K先被推断,再约束T包含该键:
export const getField = <K extends string | number | symbol, T extends Record<K, any>>(fieldName: K) => { const record = injectRecord<T>(); return { field: record[fieldName] }; }; // 调用时可以只指定T,K会自动推断 const { field } = getField<{ number: number; string: string; bool: boolean }>('bool'); // 或者显式指定K和T const { field } = getField<'bool', { number: number; string: string; bool: boolean }>('bool');
内容的提问来源于stack exchange,提问作者Renhor
相关产品推荐
相关产品推荐

