为什么打字稿不使用嵌套类型参数推断实际条件绑定类型?
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
});
我可以通过显式提供类型参数来修复它
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.
});
或者通过使用带有 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>[];
}
问题:请问这是什么原因? / 有没有一种不用强制转换也不强制调用者显式提供参数的方法?
不需要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.
在下面的代码片段中,为什么打字稿不将实际的 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
});
我可以通过显式提供类型参数来修复它
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.
});
或者通过使用带有 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>[];
}
问题:请问这是什么原因? / 有没有一种不用强制转换也不强制调用者显式提供参数的方法?
不需要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.