我如何让 Typescript 知道我的函数将克隆一个传递的只读保护参数?

How can I let Typescript know, that my function will clone a passed Readonly protected argument?

我想知道如何让 Typescript 理解 update 可以被作为第二个参数传递给 modifyState 的函数改变,因为 update 将被克隆。

// Basic example
import { clone } from 'lodash';

interface IState {
  foo: string;
}

const state: Readonly<IState> = {
  foo: "bar"
};

// Start situation
function modifyState<S>(
  prevState: S,
  updateFunc: (update: S) => void
): S {
  const newState = clone(prevState);
  updateFunc(newState);
  return newState;
}

modifyState(
  state,
  update => {
    update.foo = "another string"; // 'Cannot assign to 'foo' because it is a constant or a read-only property.'
  }
);

您可以从接收到的 Readonly<T> 值的泛型类型参数中推断出泛型类型:

function modifyState<S>(
    prevState: Readonly<S>, // <- this one
    updateFunc: (update: S) => void
): Readonly<S> {
    ...
}

我相信密码是 self-explanatory。如果需要同时支持 readonly 和 non-readonly 版本,可以使用重载签名,或者联合类型,例如:

prevState: Readonly<S> | S

在这种情况下,TypeScript 编译器将 Readonly<S> 优先于 S,如果适用的话。

您可以使用这种方法:

type Mutable<T extends { [x: string]: any }, K extends string> = {
    [P in K]: T[P];
}

...
updateFunc: (update: Mutable<S, keyof S>) => void

(code in playground)

如此处所述:Mapped Types syntax to remove modifiers