объяснение поведения оператора `keyof` для универсальных типов

#typescript #generics

#typescript #универсальные

Вопрос:

Я наткнулся на небольшую проблему, которую мне действительно удалось решить. Тем не менее, я ищу объяснение, почему это проблема в первую очередь.

Допустим, у нас есть следующие типы:

 interface Base {
    name: string;
}

interface TypeA extends Base {
    foo: number;
} 

interface TypeB extends Base {
    bar: string;
}
  

И у нас есть следующая универсальная функция:

 const genericSet = <T>(obj: T, partial: Partial<T>) => ({ ...obj, ...partial });
const demo = genericSet({ b: '222', a: 111 }, { a: 333 });
/* works great */
  

но теперь давайте вызовем функцию из другой универсальной функции:

 function doSomething<T extends Base>(obj: T) {
    const newObj = genericSet(obj, { name: 'a' }); //error!, argument {name: string} isn't assignable to Partial<T>
   ...
}
  

Но если мы определяем функцию подобным образом, в основном просто переписываем Partial

 const genericSet2 = <T, K extends keyof T>(obj: T, partial:{[key in K]?: T[key]} ) => ({ ...obj, ...partial });

  

Чем все работает!

Я просто ищу информацию, почему. Интуитивно я могу предположить, что это что-то связанное с тем, когда typescript фактически вычисляет типы, но я хотел бы конкретное объяснение того, почему это работает (если ничего другого, просто чтобы я был знаком с реальными терминами)

Если вы знаете о каких-либо соответствующих проблемах / коммитах github, это также было бы здорово.