带有数组 reduce 的 TypeScript 交集类型
TypeScript intersection types with array reduce
我正在尝试让类型与通用数组归约函数一起使用,该函数基本上合并了两个对象。以下片段是真实代码的转储版本。为什么 fl
的类型是 {}
而不是 IFoo & IBar
?
(我知道这个特定示例可以很容易地用单个 Object.assign()
调用替换。)
const flatten = <K, T>(prev: K, x: T): K & T => {
return Object.assign(prev, x);
};
interface IFoo {
foo: true;
}
interface IBar {
bar: true;
}
const fooRes: IFoo = { foo: true };
const barRes: IBar = { bar: true };
const fl = [fooRes, barRes].reduce(flatten, {});
console.log(fl); // here, fl : {}
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U
(T
是数组本身的类型参数。)所以,面对代码
[fooRes, barRes].reduce(flatten, {})
类型检查器的工作是弄清楚 U
是什么。让我们来看看它的推理:
fooRes : IFoo
和 barRes : IBar
,所以 [fooRes, barRes] : (IFoo | IBar)[]
- 因此,数组的
T ~ IFoo | IBar
- 因此调用
flatten
时其 T
参数设置为 IFoo | IBar
flatten
的 return 类型 (K & T
) 因此是 K & (IFoo | IBar)
- 由于
flatten
的 return 类型必须可分配给 U
,这给了我们约束 U >= (U & (IFoo | IBar))
,它简化为 U >= (IFoo | IBar)
- 另一个证据是
initialValue
参数,其类型为 {}
- 所以
U >= {}
- 这两个约束的最小上限是
{}
。所以类型检查器推断 U ~ {}
.
为什么没有意识到return类型是IFoo & IBar
?类型检查器不会推理代码的运行时行为——flatten
的参数在整个缩减过程中采用各种不同的类型。 (IFoo | IBar)[]
类型的数组不能保证其中同时包含 IFoo
s 和 IBar
s - 它可能只是 IFoo
s 的数组。推断 flatten
异构列表压缩其构成类型将需要相当复杂的证明,并且期望机器能够为您编写这样的证明似乎不合理。
我正在尝试让类型与通用数组归约函数一起使用,该函数基本上合并了两个对象。以下片段是真实代码的转储版本。为什么 fl
的类型是 {}
而不是 IFoo & IBar
?
(我知道这个特定示例可以很容易地用单个 Object.assign()
调用替换。)
const flatten = <K, T>(prev: K, x: T): K & T => {
return Object.assign(prev, x);
};
interface IFoo {
foo: true;
}
interface IBar {
bar: true;
}
const fooRes: IFoo = { foo: true };
const barRes: IBar = { bar: true };
const fl = [fooRes, barRes].reduce(flatten, {});
console.log(fl); // here, fl : {}
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U
(T
是数组本身的类型参数。)所以,面对代码
[fooRes, barRes].reduce(flatten, {})
类型检查器的工作是弄清楚 U
是什么。让我们来看看它的推理:
fooRes : IFoo
和barRes : IBar
,所以[fooRes, barRes] : (IFoo | IBar)[]
- 因此,数组的
T ~ IFoo | IBar
- 因此调用
flatten
时其T
参数设置为IFoo | IBar
flatten
的 return 类型 (K & T
) 因此是K & (IFoo | IBar)
- 由于
flatten
的 return 类型必须可分配给U
,这给了我们约束U >= (U & (IFoo | IBar))
,它简化为U >= (IFoo | IBar)
- 另一个证据是
initialValue
参数,其类型为{}
- 所以
U >= {}
- 这两个约束的最小上限是
{}
。所以类型检查器推断U ~ {}
.
为什么没有意识到return类型是IFoo & IBar
?类型检查器不会推理代码的运行时行为——flatten
的参数在整个缩减过程中采用各种不同的类型。 (IFoo | IBar)[]
类型的数组不能保证其中同时包含 IFoo
s 和 IBar
s - 它可能只是 IFoo
s 的数组。推断 flatten
异构列表压缩其构成类型将需要相当复杂的证明,并且期望机器能够为您编写这样的证明似乎不合理。