【问题标题】:Typescript union type not working打字稿联合类型不起作用
【发布时间】:2015-08-17 17:23:37
【问题描述】:

我有以下课程:

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;
}

在某些时候,我想迭代一组成员,如下例所示:

        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'

不知道到底出了什么问题。我看到代码的其他部分使用联合类型。

谢谢。

【问题讨论】:

    标签: types typescript typescript1.4


    【解决方案1】:

    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;
    

    【讨论】:

    • 如果用户是数字,那么此代码将不起作用getId(member.user.id),因为数字上的 id 没有属性
    【解决方案2】:

    您需要进行一些类型检查和强制转换来处理这种情况:

    (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的类型,看看它是否是一个数字,然后有条件地进行比较。

    【讨论】:

    • 这真是太好了。非常感谢。
    【解决方案3】:

    Typescript 不知道如何在你的 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.user,即 var memberUser = &lt;ISimpleUser&gt; member.user;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-16
      • 2017-05-18
      • 2019-02-06
      • 2021-08-05
      • 2018-12-06
      • 2020-11-30
      • 1970-01-01
      • 2016-03-06
      相关资源
      最近更新 更多