实际上您的第一个示例推断正确,第二个示例中的类型转换和数组类型有点不准确。在您的具体情况下,这并不重要,因为您只返回第一个元素。先来看看test:
test函数
State[T] 与 "foo"[] | "bar"[] | undefined 相同。你也可以这样写:
State[T] -> State["foo" | "bar"] -> State["foo"] | State["bar"] -> "foo"[] | "bar"[]
=> "foo"[] | "bar"[] | undefined (optional properties possible)
所以arr 在你的函数末尾有"foo"[] | "bar"[] 类型是正确的,arr[0] 类型"foo" | "bar",因为你的 if 块排除了未定义的值。 IntelliSense 显示的类型表示可能有点令人困惑,因为有时它们最终会更冗长/细化,有时更紧凑/无法解析。编译器的规范类型是相同的。
与test2比较
一开始,我说过您的强制转换数组类型有点不准确。假设我们返回 test1 和 test2 中的整个数组(不仅是第一个元素),以说明问题。
test 和 test2 的新函数签名
// test signature
<T extends Supported>(state: State, type: T): State[T]
// test2 signature
<T extends Supported>(state: State, type: T): T[] | undefined
测试用例:
// define some variables
declare const state: State;
declare const stateType: "foo" | "bar";
// invoke functions
test(state, stateType); // return type: "foo"[] | "bar"[] | undefined
test2(state, stateType); // return type: Supported[] | undefined
结果:
const test_sample1: "foo"[] | "bar"[] | undefined = ["foo", "foo"] // works
const test_sample2: "foo"[] | "bar"[] | undefined = ["foo", "bar"] // <-- error!
const test2_sample1: Supported[] | undefined = ["foo", "bar"] // works
const test2_sample2: Supported[] | undefined = ["foo", "foo"] // works
因此,在test2 中手动转换时,您可以返回["foo", "bar"],而test 则不可能。部分原因是,以下不一样:
"foo"[] | "bar"[] !== ("foo"|"bar")[]
Playground
希望,它会有所帮助。干杯