You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为提取泛型对象指定键子集的函数强类型化返回值?

问题:实现基于参数键推断的强类型返回值函数

需求是实现一个函数,传入目标类型(如Foo)和该类型的键数组,返回值为对应键的Pick类型,且键从参数中自动推断,属性类型与原类型一致:

interface Foo {
  a: string
  b: string
  c: string
}

const value = myFunction<Foo>(['b', 'c']) // value 类型必须为 Pick<Foo,'b'|'c'>

尝试的错误方案及问题

方案A:仅指定目标类型泛型

interface User {
  name: string;
  age: number;
  address: string;
}

function functionA<T extends Record<string, any>>(keys: readonly Extract<keyof T, string>[]): {[K in typeof keys[number]: T[K]]} {
  // 实现忽略
}

const u1 = functionA<User>(['address']) 
u1.name // 无错误提示,返回类型未正确限制
function functionAA<T extends Record<string, any>>(keys: readonly Extract<keyof T, string>[]): Pick<T,typeof keys[number]> {
  // 实现忽略
}

const u2 = functionAA<User>(['address']) 
u2.name // 无错误提示,返回类型未正确限制

问题:typeof keys[number]会被推断为keyof T(TypeScript无法从传入的数组字面量中窄化类型),导致返回类型等价于T而非Pick<T, 指定键>。

方案B:双泛型参数

function functionB<T extends Record<string, any>, K extends Extract<keyof T, string>>(keys: readonly K[]): Pick<T,K> {
  // 实现忽略
}

const u2 = functionB<User>(['address']) // 错误:"Expected 2 arguments, but got 1"
const u3 = functionB(['address'])
u3.address // 类型为 any

问题:必须显式传入两个泛型参数,仅传T会报错;不传泛型则T被推断为any,失去类型约束。

正确解决方案

通过泛型参数默认值和数组字面量的类型推断结合,让TypeScript自动推断键类型K,同时允许只指定目标类型T:

interface User {
  name: string;
  age: number;
  address: string;
}

function myFunction<T extends Record<string, any>, K extends keyof T = keyof T>(keys: readonly K[]): Pick<T, K> {
  // 示例实现(可根据需求替换)
  return {} as Pick<T, K>;
}

// 仅指定T,自动推断K为'address'
const u1 = myFunction<User>(['address']) 
u1.address // string
u1.name    // 报错:属性'name'不存在于类型'Pick<User, "address">'

// 自动推断T和K
const u2 = myFunction(['name', 'age'] as const)
u2.name // string
u2.age  // number
u2.address // 报错:属性'address'不存在于类型'Pick<{ name: string; age: number; }, "name" | "age">'

原理说明

  1. 给K设置默认值keyof T,当只传入T时,TypeScript会尝试从keys参数中推断更具体的K类型,而非直接使用默认值。
  2. 使用readonly K[]确保数组字面量的类型被正确窄化(配合const断言可进一步提升推断精度)。
  3. 返回类型Pick<T, K>严格限制为仅包含指定键的类型。

内容的提问来源于stack exchange,提问作者plfort

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:32:29