对于下面的代码,我使用了用Ryan Dabler's Medium post编写的算术运算类型.
以下代码片断会产生一个编译器错误
// Test interface using the Add<A, B> type
interface Foo<Sum extends number> {
increment(): Add<Sum, 1>;
incrementString(): `${Add<Sum, 1>}`;
/* ~~~~~~~~~~~
Type 'Length<[...BuildTuple<Sum, []>, any]>' is not assignable to type 'string | number | bigint | boolean | null | undefined'.
Type 'unknown' is not assignable to type 'string | number | bigint | boolean | null | undefined'.(2322) */
sumParam(param: `${Add<Sum, 1>}`): void;
/* ~~~~~~~~~~~ Same error */
}
不能将类型‘Long<;[...BuildTuple<;Sum,[]>;,any]>;’赋给类型‘字符串|数字|Bigint|布尔|空|未定义’. 类型‘UNKNOWN’不可赋值给类型‘STRING|NUMBER|BIGINT|Boolean|NULL|UNDEFINED’.(2322)
为什么我会收到这个错误?据我所知,当在interface
(或type
,就此而言)内的函数中,编译器可以解析Add<Sum, 1>
,但不能解析`${Add<Sum, 1>}`
.
下面是一些具有意外结果的其他测试,上面的代码就是上述代码.
// Testing types
type One = Add<0, 1> // 1
type OneString = `${Add<0, 1>}` // "1" - The compiler doesn't report an error. Why does it work now but not before?
// Testing with object
// I can declare all the functions even though there was an error before
const bar: Foo<0> = {
increment: () => 1,
incrementString: () => '1',
sumParam: (param: '1') => {},
}
// Testing the functions
// They all run with the expected result even though there was an error before
const baz = bar.increment() // 1
const qux = bar.incrementString() // "1"
const quux = bar.sumParam('1'); // void
Here是TS操场上的完整代码.我在那里和我的机器上测试了它.