为什么我在 Angular 项目中出现这些类型错误?

分享于2022年07月17日 angular typescript typescript-typings 问答
【问题标题】:为什么我在 Angular 项目中出现这些类型错误?(Why am I obtaining these type error in my Anuglar project?)
【发布时间】:2022-06-22 18:52:34
【问题描述】:

我正在学习 Udemy 课程后的 Angular 项目,我发现一些与类型相关的问题(我想课程讲师使用的是旧版本的 Angular,我必须以某种方式调整他的代码) .按照我的情况:

首先我有一个名为 Exercise 的模型类:

export interface Exercise {
    id: string;
    name: string;
    duration: number;
    calories: number;
    date?: Date;
    state?: 'completed' | 'cancelled' | null;
}

然后我有这个服务类:

import { Subject } from "rxjs";
import { Exercise } from "./exercise.model";

export class TrainingService {

    exerciseChanged: Subject = new Subject();
    
    private availableExercise: Exercise[] = [
        { id: 'crunches', name: 'Crunches', duration: 30, calories: 8 },
        { id: 'touch-toes', name: 'Touch Toes', duration: 180, calories: 15 },
        { id: 'side-lunges', name: 'Side Lunges', duration: 120, calories: 18 },
        { id: 'burpees', name: 'Burpees', duration: 60, calories: 8 }
    ];

    private runningExercise: Exercise | undefined | null;

    private exercises: Exercise[]  = [];

    getAvailableExercises(): Exercise[] {
        return this.availableExercise.slice();
    }

    startExercise(selectedId: string) {
        this.runningExercise  = this.availableExercise.find(ex => ex.id === selectedId) as Exercise;
        this.exerciseChanged.next({ ...this.runningExercise});

    }

    completeExercise() {
        this.exercises.push({ 
                                ...this.runningExercise as Exercise, 
                                date: new Date(), 
                                state: 'completed' 
                            });
        this.runningExercise = null;
        this.exerciseChanged.next(null);

    }

    cancelExercise(progress: number) {
        this.exercises.push({ 
            ...this.runningExercise as Exercise, 
            duration: this.runningExercise.duration,
            calories: 
            date: new Date(), 
            state: 'cancelled' 
        });
        this.runningExercise = null;
        this.exerciseChanged.next(null);

    }

    getRunningExercise() {
        return { ...this.runningExercise } as Exercise
    }
}

特别是我在这个方法代码中发现了问题:

cancelExercise(progress: number) {
    this.exercises.push({ 
        ...this.runningExercise as Exercise, 
        duration: this.runningExercise.duration,
        calories: 
        date: new Date(), 
        state: 'cancelled' 
    });
    this.runningExercise = null;
    this.exerciseChanged.next(null);

}

我的类型问题与我推入 exercises 数组的新 Exercise 对象有关:

duration: this.runningExercise.duration,

在我的控制台中给我这个错误:

Object is possibly 'null' or 'undefined'.ts(2533)

    date: new Date(), 

在我的控制台中给我这个错误:

Error: src/app/training/training.service.ts:46:13 - error TS2552: Cannot find name 'date'. Did you mean 'Date'?

46             date: new Date(),
           ~~~~

第一个似乎与我试图访问一个对象的值有关,该对象的值可以是未定义的或为空的 (this.runningExercise)。

第二个我真的不明白。

如何尝试解决这些类型的错误?


【解决方案1】:

问题 1

发件人:

private runningExercise: Exercise | undefined | null

编译器警告您该变量可能为空。虽然 duration 是数字类型,但当 runningExercise null undefined 时,该类型将 失败

在将值分配给 duration 之前,请确保在 null undefined 时处理 runningExercise 。对于下面的情况,我使用 ?. 可选链接和 ?? 空值合并运算符来处理。

问题 2

是因为上一行 calories: ,你没有赋值,后面少了 ,

this.exercises.push({ 
    ...this.runningExercise as Exercise, 
    duration: this.runningExercise?.duration ?? 0,
    calories: 1, // Assign the value and end with comma ',' 
    date: new Date(), 
    state: 'cancelled' 
});