【发布时间】:2021-05-05 09:44:28
【问题描述】:
我正在尝试生成一个通用函数,该函数允许我为给定类型生成强类型设置器,并带有回调 - 例如:
interface Foo {
a: number,
b: string
}
magick('a', 43) => {} // Should work
magick('a', '43') => {} // Should fail
我已经实现了一个通用函数来执行此操作 - 并且它有效。但是,如果我尝试复制该函数类型安全并没有强制执行(或者我更可能误解了打字稿!)
interface Test {
a: number;
b: string;
}
interface Test2 {
a2: boolean;
b2: '+' | '-';
}
const testVal: Test = {
a: 42,
b: 'test',
};
type Demo<T> = <K extends keyof T> (key: K, val: T[K]) => void
const implDemo: Demo<Test> = (key, val) => {
testVal[key] = val;
};
首先 - 该功能按我想要的方式工作:
/* prints: {a: 10, b: "test"} - correct */
implDemo('a', 10); console.log(testVal);
/* Fails as expected - type safety - a should be number */
implDemo('a', 'text');
但是为什么会出现这种情况呢?怎么可能Demo<Test2>
可分配给Demo<Test>
/* Create a pointer to implDemo - but with WRONG type!!! */
const implDemo2: Demo<Test2> = implDemo;
implDemo2('a2', true);
console.log(testVal);
/* prints: {a: 10, b: "test", a2: true} - we just violated out type!!!! */
我们刚才做的和上面做的一样:
testVal['a2'] = true; /* Doesn't work - which it shouldn't! */
这是另一种简单类型,实际上强制执行类型安全
type Demo2<T> = (val: T) => void;
const another: Demo2<string> = (val) => {};
/* This fails - as expected */
const another2: Demo2<number> = another;
这是打字稿中的错误 - 还是我误解了什么?我怀疑Demo<T> = <K extends keyof T> 类型是罪魁祸首,但我根本不明白我是如何被允许以这种方式“破解”类型系统的。
【问题讨论】:
-
是的,这在我看来像是一个编译器错误;不确定是否已经被举报。
标签: typescript