我只读取了打字稿中的数据和一个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';
Run Code Online (Sandbox Code Playgroud)
如何声明clone函数以便它返回的对象的属性是可写的?
knp*_*wrs 13
有一种更新的方法可以实现这一点,但我认为更新已经存在的答案并不是记录这一点的最佳方式。
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
Run Code Online (Sandbox Code Playgroud)
这具有保留可选修饰符并且只需要一个通用参数的额外好处。
(操场上的代码)
目前的做法是:
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>;
Run Code Online (Sandbox Code Playgroud)
(操场上的代码)
如此处所述:删除修饰符的映射类型语法。
我很确定没有办法取消readonly限制,例如:
declare function clone<T>(val: T): {[K in keyof T]: T[K]};
const rw = clone(ro);
rw.foo = 'changed';
Run Code Online (Sandbox Code Playgroud)
仍然会产生只读错误。
不过,您可以做相反的事情,从“可写”接口开始并将其限制为只读:
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';
Run Code Online (Sandbox Code Playgroud)
请注意,我已从Data类更改为接口,因为您在示例中没有将其用作类。
如果你想将它作为一个类使用,你需要实例化它:
const ro = new Data();
ro.foo = "bar";
Run Code Online (Sandbox Code Playgroud)
或者
const ro = Object.assign(new Data(), { foo: "bar" });
Run Code Online (Sandbox Code Playgroud)
我收回刚才的话,你实际上可以忽略 readonly 修饰符:
declare function clone<T>(val: T): {[K in (keyof T)]: T[K]};
const rw = clone(ro);
rw.foo = 'changed';
Run Code Online (Sandbox Code Playgroud)
工作正常,区别(keyof T)不仅仅是keyof T,还有一个问题:带有修饰符的映射类型错误被标记为错误。
| 归档时间: |
|
| 查看次数: |
4694 次 |
| 最近记录: |