声明一个克隆函数,使Readon属性可以在TypeScript中写入?

时间:2017-02-13 22:30:41

标签: typescript

我只读取了打字稿中的数据和{page:1,total:1,records:1, rows: ...}函数:

clone

如何声明class Data { readonly foo: string; } const ro: Data = { foo: 'bar' } // how to declare clone so that it returns writable data? declare function clone<T>(val: T): T; const rw = clone(ro); // how to make the properties of rw writable? rw.foo = 'changed'; 函数以便它返回的对象的属性是可写的?

3 个答案:

答案 0 :(得分:3)

目前的做法是:

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

declare function clone<T>(val: T): Mutable<T, keyof T>;

code in playground

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

原始答案:

我非常确定无法删除readonly限制,例如:

declare function clone<T>(val: T): {[K in keyof T]: T[K]};
const rw = clone(ro);
rw.foo = 'changed';

仍然产生只读错误。

你可以做相反的事情,从&#34;可写&#34;开始接口并将其限制为只读:

interface Data {
    foo: string;
}

const ro: Readonly<Data> = {
    foo: 'bar'
}
declare function clone<T>(val: Readonly<T>): T;

const rw = clone(ro);
rw.foo = 'changed';

请注意,我已将Data从一个类更改为接口,因为您未在示例中将其用作类。
如果要将其用作类,则需要实例化它:

const ro = new Data();
ro.foo = "bar";

或者

const ro = Object.assign(new Data(), { foo: "bar" });

之前的编辑使用了一个错误使用的错误:

我收回它,你实际上可以忽略readonly修饰符:

declare function clone<T>(val: T): {[K in (keyof T)]: T[K]};
const rw = clone(ro);
rw.foo = 'changed';

工作正常,区别在于(keyof T)而不仅仅是keyof T,其中存在一个问题:Mapped Type bug with modifiers被标记为错误。

答案 1 :(得分:2)

有一种更新的方法可以实现这一目标,但我不认为更新已经存在的答案将是记录此问题的最佳方式。

type Mutable<T> = {
    -readonly [P in keyof T]: T[P];
};

这具有保留可选修饰符和仅需要一个通用参数的额外好处。

code in playground

答案 2 :(得分:0)

另一种对我有用的替代方法:

let config = JSON.parse(JSON.stringify(require('src/assets/config.json')));

在我的例子中,如果我直接使用 config,变量 require 出于某种原因变为只读。