在此示例TypeScript代码中,我声明了一个具有conditional return type的函数。
/**
* Do all elements of `a` appear in `b` and in the same order?
*/
declare function isSubarrayOf<T, U>(
a: ReadonlyArray<T>,
b: ReadonlyArray<U>
): T extends U ? boolean : false;
如果数组a
可能是数组b
的子数组,则键入T
必须分配为类型U
,因此函数返回boolean
。相反,如果T
不扩展U
,则没有办法 a
可能是b
的子数组,因此该函数必须返回false
。
我尝试在此测试中获得false
,但仍被推断为boolean
。
let a: number[] = [1, 2, 3]
let b: (string | number)[] = [1, 2, '3']
let test1: boolean = isSubarrayOf(a, b)
let test2: false = isSubarrayOf(b, a) // unexpected error!
/*
* WAT?
* `b` could never be a subarray of `a`,
* since `string|number` is not assignable to `number`,
* so the type of `test2` should be `false`.
* however, the inferred type is boolean???
*/
所以我做了一些更多的测试,以确保我不会发疯,但是这些测试都通过了。
/*
* testing: is `string|number` assignable to `number`?
* if yes, `x` should be assignable to `y`.
* if no, should get an error.
*/
let x: string | number = 'x'
let y: number = x // expected error
/*
* testing: does `(string | number) extends number`?
* if yes, `test3` should be `boolean`, assigned true.
* if no, should be `false`, should get an error.
*/
let test3: (string | number) extends number ? boolean : false
= true // expected error
我错过了什么吗?或者这是一个错误?
答案 0 :(得分:2)
我相信您真正想要的是:
declare function isSubarrayOf<T, U>(
a: ReadonlyArray<T>,
b: ReadonlyArray<U>
): [T] extends [U] ? boolean : false;
请注意[T]
和[U]
周围的方括号。该语法告诉TypeScript不要在联合类型上分配,这在使用条件类型时会发生。参见distributive conditional types。
进行此更改后,您的函数将如下所示:
isSubarrayOf([1], [1]) // potentially true (the type is the same)
isSubarrayOf([1], ['1']) // false (they have nothing in common)
isSubarrayOf(['1'], [1]) // false (they have nothing in common)
isSubarrayOf(['1'], [1, '1']) // potentially true (first is more narrow than the second)
isSubarrayOf(['1', 1], [1]) // false (first is wider)