为什么打字稿不使用嵌套类型参数推断实际条件绑定类型?

Why doesn't typescript infer actual conditional bound type with nested type argument?

在下面的代码片段中,为什么打字稿不将实际的 F 类型推断为函数 return 类型,而仅将其推断为绑定 (GenericPerson)没有 'address' 属性?

type GenericPerson = { name: string; };
type GenericCompany<X extends GenericPerson> = { companyName: string; employees: X[]; };

const getEmployeeDetails= <F extends GenericPerson, T extends GenericCompany<F>>(company: T): F[] => {
  return company.employees;
};

getEmployeeDetails({
  companyName: 'XYZ',
  employees: [
    {
      name: 'John',
      address: 'London',
    }
  ],
}).map((x) => {
  console.log(x.address); // Property 'address' does not exist on type GenericPerson
});

[Playground]

我可以通过显式提供类型参数来修复它

type ExtendedPerson = {name: string; address: string};
getEmployeeDetails<ExtendedPerson, GenericCompany<ExtendedPerson>>({
  companyName: 'XYZ',
  employees: [
    {
      name: 'John',
      address: 'London',
    }
  ],
}).map((x) => {
  console.log(x.address); // Type-checks.
});

[Playground]

或者通过使用带有 infer 的条件(我必须插入强制转换)

type InferMe<T extends GenericCompany<any>> = T extends GenericCompany<infer R> ? R : never;

function getEmployeeDetails<F extends GenericPerson, T extends GenericCompany<F>>(company: T): InferMe<T>[] {
  return company.employees as InferMe<T>[];
}

[Playground]

问题:请问这是什么原因? / 有没有一种不用强制转换也不强制调用者显式提供参数的方法?

不需要F泛型类型变量,可以简化为:

const getEmployeeDetails = <T extends GenericCompany<GenericPerson>>(company: T): T['employees'] => {
  return company.employees;
};

这应该可以完成工作:

function getEmployeeDetails<F extends GenericPerson>(company: GenericCompany<F>): F[] {
    return company.employees;
}

getEmployeeDetails({ companyName: 'XYZ', employees: [{ name: 'John', address: 'London' }], })
    .map(x => console.log(x.address)); // property 'address' recognized correctly.