我们正在寻找一种使用Object.assign的类型安全的方法.但是,我们似乎无法使其发挥作用.
为了显示我们的问题,我将使用Generics文档中的copyFields方法
function copyFields<T extends U, U>(target: T, source: U): T {
for (let id in source) {
target[id] = source[id];
}
return target;
}
function makesrc(): Source { return {b: 1, c: "a"}}
interface Source {
a?: "a"|"b",
b: number,
c: "a" | "b"
}
Run Code Online (Sandbox Code Playgroud)
我希望引擎阻止我创建未声明的属性
/*1*/copyFields(makesrc(), {d: "d"}); //gives an error
/*2*/copyFields(makesrc(), {a: "d"}); //gives an error
/*3*/copyFields(makesrc(), {c: "d"}); //should give an error, but doesn't because "a"|"b" is a valid subtype of string.
//I don't want to specify all the source properties
/*4*/copyFields(makesrc(), {b: 2}); //will not give me an error
/*5*/copyFields(makesrc(), {a: "b"}); //should not give an error, but does because string? is not a valid subtype of string
Run Code Online (Sandbox Code Playgroud)
我们试图通过明确地向copyfields调用提供类型来解决这个问题,但我们找不到一个能让所有例子都起作用的调用.
例如:为了使5工作你可以像这样调用copyFields:
/*5'*/copyFields<Source,{a?:"a"|"b"}>(makesrc(), {a: "b"});
Run Code Online (Sandbox Code Playgroud)
但是对Source类型的后续更改(例如删除"b"选项)现在将不再导致类型错误
有谁知道如何使这项工作?
Typescript 2.1.4 来救援!
interface Data {
a?: "a"|"b",
b: number,
c: "a" | "b"
}
function copyFields<T>(target: T, source: Readonly<Partial<T>>): T {
for (let id in source) {
target[id] = source[id];
}
return target;
}
function makesrc(): Data { return {b: 1, c: "a"}}
/*1*/copyFields(makesrc(), {d: "d"}); //gives an error
/*2*/copyFields(makesrc(), {a: "d"}); //gives an error
/*3*/copyFields(makesrc(), {c: "d"}); //gives an error
//I don't want to specify all the source properties
/*4*/copyFields(makesrc(), {b: 2}); //will not give me an error
/*5*/copyFields(makesrc(), {a: "b"}); //will not give me an error
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
767 次 |
| 最近记录: |