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

如何定义仅包含T的任意可选属性的泛型类型IncompleteVariant?

解决IncompleteVariant泛型类型定义与TypeScript赋值错误问题

我需要定义一个泛型类型IncompleteVariant<T>,它的属性类型与T一致,但所有属性均为可选(支持空对象{}),用于orInitialState函数中。尝试使用type IncompleteVariant<T> = NonNullable<Partial<T>>时,出现TypeScript错误:

Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'.ts(2322)

相关函数代码:

/**
 * Modifies the passed `newState` to fallback on the `initialState` if any property is not set.
 */
export function orInitialState<T extends object> (newState: IncompleteVariant<T>, initialState: T): T {
  type Key = keyof T;
  if(!newState) return initialState;
  const newerState: T = {...initialState}
  for(const key of Object.keys(initialState)) {
    if(newState.hasOwnProperty(key as Key)) newerState[key as Key] = newState[key as Key]
  }
  return newerState;
}

错误原因

NonNullable<Partial<T>>仅排除了newState整体为null或undefined的情况,但Partial<T>会将每个属性的类型改为T[K] | undefined。当尝试把newState[key]赋值给类型为T的newerState[key]时,TypeScript会认为可能将undefined赋值给不允许undefined的属性,因此抛出错误。

解决方案

方案1:保留Partial<T>定义,添加类型断言或类型守卫

子方案1.1:直接添加类型断言

修改循环内的赋值代码,明确告诉TypeScript当前属性值不是undefined:

for(const key of Object.keys(initialState)) {
  const keyTyped = key as Key;
  if(newState.hasOwnProperty(keyTyped)) {
    newerState[keyTyped] = newState[keyTyped] as T[Key];
  }
}

同时将IncompleteVariant<T>定义为:

type IncompleteVariant<T> = NonNullable<Partial<T>>;

子方案1.2:使用类型守卫函数

定义一个类型守卫来判断值是否非undefined,让TypeScript自动推断类型:

function isDefined<T>(value: T | undefined): value is T {
  return value !== undefined;
}

// 修改函数内的循环逻辑:
for(const key of Object.keys(initialState)) {
  const keyTyped = key as Key;
  const value = newState[keyTyped];
  if(newState.hasOwnProperty(keyTyped) && isDefined(value)) {
    newerState[keyTyped] = value;
  }
}

此时IncompleteVariant<T>仍可使用NonNullable<Partial<T>>定义。

方案2:重新定义IncompleteVariant<T>,限制可选属性值非undefined

如果业务逻辑要求:只要newState包含某个属性,其值就不能是undefined,可以这样定义IncompleteVariant<T>:

type IncompleteVariant<T> = { [K in keyof T]?: NonNullable<T[K]> };

这个定义会让每个可选属性的类型变为T[K]排除undefined后的类型,确保赋值时不会出现类型不兼容问题。

注意:如果T本身的属性允许undefined,这个方案会自动排除undefined,可能不符合预期,此时建议使用方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:55:17