играя с TS 3.7.2 Я обнаружил странный крайний случай, и теперь мне интересно узнать больше о том, как вывод типа в функции работает в этом конкретном c случае.
interface A {
functions: { t: number, a: { test: number }; };
}
interface B {
functions: { t: number, b: { ciao: number }; };
}
function combineStuff<TNamespace extends {}>(stuff: { functions: Partial<TNamespace> }[]): TNamespace {
// Implementation irrelevant for the question
return {functions: merge({}, ...stuff.map(s => s.functions))} as any;
}
const a: A = { functions: { t: 1, a: { test: 1 } } };
const b: B = {functions: { t: 1, b: { ciao: 2 } }};
const c = combineStuff([a, b]);
c.a.test;
c.b.ciao; // Error. Why is that?
const d = combineStuff<A['functions'] & B['functions']>([a, b]);
d.a.test;
d.b.ciao; // Works well
Я ожидал, что и c.b.ciao
, и d.b.ciao
были безопасны по типу, но доступ к c.b.ciao
вызывает ошибку.
Из этого простого примера видно, что тип generi c может быть автоматически выведен из элементов этого массива, эта гипотеза также подтверждается тем фактом, что в вызове combineStuff<A['functions'] & B['functions']>([a, b]);
компилятор TS проверяет, что типы a
и b
действительно правильные.
Кроме того, вывод типа работает правильно для первого элемента массива a
я могу безопасно ввести тип c.a.test
.
Почему мне нужно явно указать тип generi c для combineStuff()
, чтобы получить правильный результат ? Почему вывод первого элемента массива работает правильно?