当与受约束的泛型类型一起使用时,Typescript类型保护不能推断正确的类型

问题描述

在下面的代码中,我希望data具有智能感知提供的.company_id属性。但是,我仅获得共同财产。请参见下图。


type UserPairingg = {pairing_type: 'user',user_id: number};
type CompanyPairingg = {pairing_type: 'company',company_id: number};
type Pairingg = UserPairingg | CompanyPairingg; 

function parsee<T extends Pairingg>(data: T): T {
   if (data.pairing_type === "company") {
      data. // why doesn't it show company_id?
   }
}

我在做什么错?

enter image description here

解决方法

很遗憾,TypeScript尚无法实现。您要么必须显式转换它,要么使用predicate method

type UserPairingg = {pairing_type: 'user',user_id: number};
type CompanyPairingg = {pairing_type: 'company',company_id: number};
type Pairingg = UserPairingg | CompanyPairingg; 

function parsee<T extends Pairingg>(data: T): T {
   // inline predicate
   if (((d: Pairingg): d is CompanyPairingg => d.pairing_type === "company")(data)) {
      data.company_id;
   }

   // function predicate
   if (isCompanyPairing(data)) {
      data.company_id;
   }

   return data;
}

function parsee2<T extends Pairingg>(data: T): T {
   if (data.pairing_type === "company") {
      const companyPairing = data as CompanyPairingg;
      
      companyPairing.company_id;
   }

   return data;
}

function isCompanyPairing(data: Pairingg): data is CompanyPairingg {
   return data.pairing_type === 'company';
}

Playground Link

,

如果您想更频繁地检查用户配对或公司配对,可以为此创建 type guards

type UserPairing = {pairing_type: 'user',user_id: number};
type CompanyPairing = {pairing_type: 'company',company_id: number};
type Pairing = UserPairing | CompanyPairing; 

function parse<T extends Pairing>(data: T): T {
   if (isCompanyParing(data)) {
      console.log(data.company_id);
   }
   if(isUserParing(data)) {
       console.log(data.user_id);
   }

   return data;
}

function isCompanyParing(data: Pairing): data is CompanyPairing {
    return data.pairing_type === 'company';
}

function isUserParing(data: Pairing): data is UserPairing {
    return data.pairing_type === 'user';
}
,

您仍然需要强制转换您的“数据”。

(data as CompanyPairingg).company_id