错误 TS2741:在类型中缺少属性

9
在文件 models/User.model.ts 中(见下方),我尝试设置了一个名为 isEqual 的方法,具体的代码如下。请问是否有人能够指出我的代码错误?
文件 models/User.model.ts:
export class User {
    constructor(
    public firstName: string,
    public lastName: string,
    ) {}

    isEqual (other : User): boolean {
    return other === this;
    }
}

文件服务/user.service.ts:

import { User } from '../models/User.model';
import { Subject } from 'rxjs/Subject';

export class UserService {

    private users: User[] = [
    {
        firstName: 'William',
        lastName: 'Jones'
    },
    {
        firstName: 'John',
        lastName: 'Doe'
    }
    ];

services/user.service.ts(7,2)中出现错误: error TS2741: 在类型 'User' 中,属性 'isEqual' 在类型 '{ firstName: string; lastName: string;}' 中缺失,但是它是必需的。


4
你不能仅仅说{ firstName: 'John', lastName: 'Doe' }是一个User,因为它并不是。你需要使用new User('john', 'doe');的方式来创建一个用户。 - Erik Philips
@ErikPhilips 非常不幸,这也是我对 TypeScript 感到沮丧的原因之一。其他语言没有问题处理那种语法。 - marknuzz
@nuzzolilo,还有哪些语言支持在不指定/调用构造函数的情况下创建对象? - Erik Philips
@ErikPhilips 抛开默认构造函数的语义(这不是问题所在):JS、C#、F#、Java、C99、C++20(通过指定初始化程序)、Python,现在还有 TS 通过 Partial<T> 等等都支持。如果修改构造函数是一种选择,我已经添加了一个答案来展示如何在 TS 中完成此操作。 - marknuzz
@nuzzolilo 我对默认构造函数持不同意见。new operator 在功能上做了许多不调用 new 就无法实现的事情。与你帖子中提到的大多数相关语言一样,new 对于构建用户定义类是必需的。虽然可能有避免调用构造函数的方法(如 c#),但除了一些重大异常情况外,它很少被使用。 - Erik Philips
@ErikPhilips 我认为没有人抱怨需要输入“new”。问题在于你是否必须精心设计构造函数以明确处理类中的每个字段!使用对象字面量而不是构造函数语法的好处在于,您可以指定要求所有字段都是默认值,除了您在该字面量中明确指定的内容,而无需考虑构造函数中字段的顺序。在C#中,通过文字值实例化对象时仍会调用默认构造函数。 - marknuzz
4个回答

5
在services/user.service.ts文件中,出现了错误,具体是在第7行第2列。错误提示为:缺失属性'isEqual',但在类型“User”中是必需的,而在'firstName'和'lastName'中,虽然已经有用户信息,但仍然需要一个函数“isEqual”,因为它已经在类定义中声明。此外,请注意,用户的类型应该是“User”,而不是“Users”。请检查和修正这些问题。
{
  firstName: 'William',
  lastName: 'Jones'
},

如评论中所述,您可以使用new ()来创建一个新的User,其中应该还包括该函数。

public exampleUser = new User("William", "Jones");

这样可以在一个Users数组中使用。
public users: Users =  [ this.exampleUser ];

我不明白在代码中应该在哪里编写这个新用户。你能再明确一些吗? - Emile Achadde
1
你可以使用公共用户:Users = [new User("john", "Doe"), new User("william", "jones")]; 等等 :-) - devDan
这有帮助您解决问题吗? - devDan
非常感谢。现在isEqual方法被正确解释了。我按照您所说的做了:public wj = new User('William', 'Jones'); public jd = new User('John', 'Doe'); public users = [this.wj, this.jd]; - Emile Achadde
我不知道如何制作投票或在评论中换行。抱歉。无论如何,你帮了很多忙。 - Emile Achadde

1

这是在指定函数isEqual中所需参数的类型或模型应为{ firstName: 'John', lastName: 'Doe' },这表明您只需要按照此格式传递数据。


1
也许您不喜欢这种用法,但如果您不需要对数组中的项目使用isEqual,则可以将该方法设置为可选项。
在方法名称后添加问号(?)。
isEqual?(other: User): boolean

但是,如果你需要对所有项目使用isEqual,那么这个解决方案就不适用了,正如我在开始时所说的。通过这种用法,当你尝试使用isEqual方法时,它会给出undefined错误。


1
自从支持 Partial<T> 以后,你现在可以将 User 的构造函数更改为下面这样,并且你应该能够通过指定键和值的部分哈希来初始化对象(就像你之前尝试过的那样)。
constructor(init?:Partial<User>) {
    Object.assign(this, init);
}

从文档(目前位于https://www.typescriptlang.org/docs/handbook/utility-types.html#partialt)中得知:
构造一个类型,其中T的所有属性都设置为可选。此实用程序将返回表示给定类型所有子集的类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接