2015-06-03 193 views
3

我有以下類別:打字稿聯合類型不工作

export interface ISimpleUser { 
    id: number; 
    full_name: string; 
} 


export interface IMember extends ng.resource.IResource<IMember> { 
    id: number; 
    project: number; 
    user: number|ISimpleUser; 
    skills: ISkill[]; 
    about: string; 
    accepted: Boolean; 

    updated: Date; 
    created: Date; 
} 

在某些時候,我想遍歷狀構件在下面的示例中的arroy:

 return angular.forEach<resources.IMember>(this.project.members, 
      (member: resources.IMember) => { 
       return member.user.id == user.id; 
      }).length > 0; 

,但我得到這個錯誤:

error TS2339: Property 'id' does not exist on type 'number | ISimpleUser' 

確切地不知道什麼是錯。我看到代碼的其他部分使用聯合類型。

謝謝。

回答

4

你需要做一些類型檢查和鑄造處理這種情況:

(member: resources.IMember) => { 
    return member.user.id == user.id; 
    if (typeof (member.user) === 'number') { 
    return member.user == user.id; 
    } else { 
    return (<ISimpleUser>member.user).id == user.id; 
    } 
}).length > 0; 

只是因爲你知道可能的類型在代碼/設計時間並不意味着編譯代碼知道類型在運行時。所以,你可以檢查member.user類型,看它是否是一個數字,然後有條件地做你的比較。

+0

這真的很好。非常感謝。 –

2

TypeScript(和JavaScript)中的number類型沒有id屬性。要在沒有保護類型檢查的情況下使用聯合類型的屬性(以破壞聯合類型),屬性必須具有相同的名稱和類型。例如,如果user財產被定義是這樣的:

user: IOtherThing|ISimpleUser; 

IOtherThing有一個id屬性,那麼它會工作。

我猜測,但你可能會不得不做這樣的事情:

var getId = (id: number | IMember) => { 
     if (typeof id === "number") { 
      return id; 
     } else { 
      return id.id; 
     } 
    }; 
return angular.forEach<resources.IMember>(this.project.members, 
    (member: resources.IMember) => { 
     return getId(member.user.id) === getId(user); 
    }).length > 0; 
+2

如果用戶是一個數字那麼這段代碼將無法正常工作'的getId(member.user.id)',因爲是在ID沒有財產上的一些 – Brocco

+0

編輯 - 感謝。 – NYCdotNet

2

打字稿不知道如何在您的foreach處理member.user,你需要把邏輯在typeof if聲明:

return angular.forEach<resources.IMember>(this.project.members, (member: resources.IMember) => { 
    var memberUser = member.user; 

    if(typeof memberUser === 'number'){ 
     return memberUser === user.id; 
    } else if (typeof member.user === 'object') { 
     return memberUser.id === user.id; 
    } 
}).length > 0; 

通過使用typeof TypeScript可以推斷您想要在哪個點使用哪種類型。

或者,如果你知道你的列表只包含ISimpleUser,那麼你可以施放member.uservar memberUser = <ISimpleUser> member.user;