很抱歉,对于更熟悉类型系统的人来说,这可能是一个简单的问题。为什么在typescript中内联条件会得到不同的结果?
例如,如果我使用Extract条件,如果我内联它,与将它用作泛型相比,我会得到不同的行为:
// setup
type TUnion = ['foo', 1] | ['baz', 2];
type TDiscriminator = ['foo', any];
// using the conditional generic
type Extract<T, U> = T extends U ? T : never;
type TExtracted = Extract<TUnion, TDiscriminator>; // ["foo", 1]
// inlining the conditional
type TInlined = TUnion extends TDiscriminator ? TUnion : never; // never
当我进一步推动这一点时,似乎需要传递T的值:
type ExtractWithU<T> = T extends TDiscriminator ? T : never;
type TExtractedWithU = ExtractWithU<TUnion>; // ["foo", 1]
type ExtractWithT<U> = TUnion extends U ? TUnion : never;
type TExtractedWithT = ExtractWithT<TDiscriminator>; // never
我是不是错过了一些简单的东西?
从上面带有jcalz和Titian的注释链来看,问题是泛型正在分发,而内联的则没有。
具体为
// setup
type TA = ['foo', 1];
type TB = ['baz', 2];
type TUnion = TA | TB;
type TDiscriminator = ['foo', any];
// using the conditional generic
type Extract<T, U> = T extends U ? T : never;
type TExtracted = Extract<TUnion, TDiscriminator>; // ["foo", 1]
// = Extract<TA | TB, TDiscriminator>
// = Extract<TA, TDiscriminator> | Extract<TB, TDiscriminator>
// = TA | never
// = TA
// inlining the conditional
type TInlined = TUnion extends TDiscriminator ? TUnion : never; // never
// = never, because the union isn't a subtype of the discriminator