【发布时间】:2022-03-11 08:00:47
【问题描述】:
我们正在寻找一种使用 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"
}
我希望引擎阻止我创建未声明的属性
/*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
我们已尝试通过显式向 copyfields 调用提供类型来解决此问题 但我们找不到可以使所有示例都正常运行的调用。
例如: 要完成 5 项工作,您可以像这样调用 copyFields:
/*5'*/copyFields<Source,{a?:"a"|"b"}>(makesrc(), {a: "b"});
但对 Source 类型的后续更改(例如删除“b”选项)现在将不再导致类型错误
有没有人知道如何实现这个功能?
【问题讨论】:
-
看看
&类型运算符。 -
顺便说一句,我们(Rene 是我的同事)发现 flow 确实支持这个用例 tryflow.org/?code=ZGVjbGFyZSBpbnRlcmZhY2UgU291cmNlIHsKICAgIGE/…
-
@torazaburo 不会使所需示例失败
标签: typescript