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

如何在TypeScript中按引用传递属性以实现类型安全更新?

TypeScript类型安全的属性读写问题

通过名称读取对象属性的方式有很多种,但这些方式似乎都无法在不进行显式类型转换的情况下更新属性。

我们需要一个能安全读写属性值的类型安全函数,原始场景是编辑属性值,为简化说明,本文以给属性值追加空格为例。

读取正常,但更新报错的实现

1. 使用{ [k in K]: string }和keyof T

function appendSpace1<
    T extends { [k in K]: string },
    K extends keyof T
>(obj: T, path: K) {
  let x = obj[path]; // `x` is `T[K]`
  let y = x + " ";   // `y` is `string`
  obj[path] = y;     // Type 'string' is not assignable to type 'T[K]'.(2322)
  return x;
}

2. 使用Record<K, string>和string

function appendSpace2<
    T extends Record<K, string>,
    K extends string
>(obj: T, path: K) {
  let x = obj[path]; // `x` is `T[K]`
  let y = x + " ";   // `y` is `string`
  obj[path] = y;     // Type 'string' is not assignable to type 'T[K]'.(2322)
  return x;
}

3. 使用Record<K, string>和KeysWithValsOfType<T, V>

type KeysWithValsOfType<T, V> = keyof {
  [P in keyof T as T[P] extends V ? P : never]: P;
};

function appendSpace3<
    T extends { [k in K]: string },
    K extends KeysWithValsOfType<T, string>
>(obj: T, path: K) {
  let x = obj[path]; // `x` is `T[K]`
  let y = x + " ";   // `y` is `string`
  obj[path] = y;     // Type 'string' is not assignable to type 'T[K]'.(2322)
  return x;
}

读写正常,但存在局限的实现

1. 使用类

使用类时该方案可行,但将代码转换为泛型类型时会失败:

type MyClass = {
  a: number;
  b: number ;
  c: string ;
}

function increment<T>(obj: T,
     key: {
      [K in keyof T]-?: number extends T[K] ? K : never
    }[keyof T]
  ) {
    obj[key]++; // fail
  }

const test: MyClass = {a: 0, b: 1, c: "two"};

increment(test, "a");
increment(test, "b");
increment(test, "c"); // fail
increment(test, "d"); // fail

2. 使用常量属性名

function appendSpace4<
    T extends { x: string },
    K extends "x"
>(obj: T, path: K) {
  let x = obj[path]; // `x` is `T[K]`
  let y = x + " ";   // `y` is `string`
  obj[path] = y;     // OK!
  return x;
}

但该方案不支持参数化,一旦将x改为[k in K]或keyof T,obj[path] = y就会再次出现ts2322错误。

我似乎已经接近解决方案,但始终无法完全实现,为何更新操作的类型检查如此不同?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:48:18