使用 TypeScript 的联合类型时 Angular 模板检查错误

标签 angular typescript

界面

export interface Review {
  _id: string;
  locationId: string;
  rating: number;
  review: string;
  userId: user | string;
}

interface user {
  _id: string;
  profile_pic: string;
  first_name: string;
  last_name: string;
}

TS文件

reviews: Review[];

在模板中使用

<div *ngFor="let review of reviews">
  <img [src]="review.userId.profile_pic">
</div>

错误

Identifier 'profile_pic' is not defined. 'string | user' does not contain such a member

上面的错误在我的 IDE 中是可见的。但是当我在浏览器上运行它时工作正常。

最佳答案

如果您真的想坚持使用当前架构,您可以使用 custom pipe将 userID 的类型设置为 user,您知道 myUser 不会是字符串。像这样的东西:

import { Pipe, PipeTransform } from '@angular/core';
// You will also need to import your `user` interface
@Pipe({name: 'assignUserType'})
export class ExponentialStrengthPipe implements PipeTransform {
    transform(myUser): User {
        return myUser as User;
    }
}

然后你可以在你的模板中使用它:

{{review.userId | assignUserType}}

如您所料,如果 myUser 不满足您的接口(interface) user,这将出错。

tl;dr - 我会在答案底部使用方法 3。

根据 @abhishek-ekaanth 的评论,我不推荐这种方法:

userId: user | string;

除了错误之外,这将很可能在某些时候给您带来问题,因为有两种不同的可能路径指向用户 ID,具体取决于 userId 是否为字符串。

如果在某些情况下,您可能只有 userId 而没有分配给 Reviewuser,您可以采用以下方法之一以下方法:

方法 1:

userIduser 分成两个单独的属性,并使 user 可选:

export interface Review {
    _id: string;
    locationId: string;
    rating: number;
    review: string;
    userId: string;
    user?: user;
}

如果您想避免在出现user 的地方重复userId,您也可以将userId 设为可选并填充其中一个,但根据我的第一点,我认为这会让你头疼。

然后在您的模板中您可以:

<div *ngFor="let review of reviews">
    <img *ngIf="review.user" [src]="review.user.profile_pic">
</div>

只有在填充了 review.user 时才会显示图片。

方法 2:

可能更接近您的初始方法:

export interface Review {
    _id: string;
    locationId: string;
    rating: number;
    review: string;
    user: user;
}

interface user {
    _id: string;
    profile_pic?: string;
    first_name?: string;
    last_name?: string;
}

所以如果你只有一个用户 ID,user 就是:

{
    _id: 'myUserID'
}

这避免了在 Review 中重复用户 ID,并且具有指向用户 ID 的一致路径的好处,无论 user 的其他属性是否被填充。

缺点是使 user 的所有其他属性可选很尴尬。

然后你可以这样做:

<div *ngFor="let review of reviews">
    <img *ngIf="review.user.profile_pic" [src]="review.user.profile_pic">
</div>

方法 3:

...因为好事成三 - 这就是我会使用的。

export interface Review {
    _id: string;
    locationId: string;
    rating: number;
    review: string;
    user: user;
}

interface user {
    _id: string;
    userProperties?: UserProperties;
}

interface UserProperties {
    profile_pic: string;
    first_name: string;
    last_name: string;
}

在你的模板中:

<div *ngFor="let review of reviews">
    <img *ngIf="review.user.userProperties" [src]="review.user.userProperties.profile_pic">
</div>

关于使用 TypeScript 的联合类型时 Angular 模板检查错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61885668/

相关文章:

javascript - Angular 7 - 为动态创建的组件添加拖放行为

javascript - 在 Angular2 上使用正则表达式制作管道

javascript - 如何使用 TypeScript 在 Angular 2 的浏览器中获取当前 url?

javascript - 具有动态行的 Angular 2 Material 数据表

javascript - RXJS 可观察对象上方法 .pipe() 和 .subscribe() 的区别

html - 是否可以将 Mat-Checkbox 样式设置为显示 X 而不是复选标记?

Angular - 动态加载图像

typescript - 以简单/缩小的方式定义类成员

angular - Jasmine:Matcher 不同于 undefined 和 null (!= undefined and != null)

javascript - 如何在 Angular 4中过滤JSON数据