简体   繁体   English

打字稿抱怨没有分配get属性

[英]Typescript complaining about not assigning a get property

I have this code stackblitz 我有这个代码stackblitz

export class Student {
  id: number;
  name: string;
  age?:number;

  get studentType():string {
    return 'fullTime'
  }

  constructor(params: Student) {
    Object.assign(this, params);
  }
}

const student = new Student({id:1, name: 'Jon'}); //ts error here

I get the below error 我收到以下错误

Argument of type '{ id: number; 类型'{{id:number; name: string; 名称:字符串; }' is not assignable to parameter of type 'Student'. }”不能分配给“学生”类型的参数。 Property 'studentType' is missing in type '{ id: number; 类型'{id:number;缺少属性'studentType'。 name: string; 名称:字符串; }'. }”。

While studentType is a get only property and can't bet set. 虽然studentType是仅获取属性,无法下注设置。

What is the reason for that and how can I solve it? 原因是什么,我该如何解决?

ps. PS。 (I don't want to make it nullable like studentType? or convert it to just a function) (我不想像studentType?那样使它为可空值或将其转换为一个函数)

Getters / Setters are exactly like regular properties, thats why Typescript can't distinguish between a getter / setter and a regular property. Getters / Setters与常规属性完全一样,这就是为什么Typescript不能区分getter / setter和常规属性。 You could make all properties optional though, with that you can omit the studentType : 您可以将所有属性设置为可选,从而可以省略studentType

  constructor(params: Partial<Student>) {
     Object.assign(this, params);
  }

However other properties (eg name ) could also be omitted now. 但是,其他属性(例如name )现在也可以省略。 To make that more typesafe you could introduce an additional interface: 为了提高类型安全性,您可以引入其他接口:

export interface StudentData {
  id: number;
  name: string;
  age?:number;
}

export class Student implements StudentData {
  get studentType():string {
    return 'fullTime'
  }

  constructor(params: StudentData) {
     Object.assign(this, params);
   }
 }

That is a more controversial topic in TypeScript. 在TypeScript中,这是一个更具争议性的话题。 For class, TypeScript consider the overall shape of the class to be the type. 对于类,TypeScript将类的整体形状视为类型。

This includes private variables and methods, and in this case, including the getter/setter. 这包括私有变量和方法,在这种情况下,包括getter / setter。

One solution to your problem is you can use Partial<> 解决问题的一种方法是可以使用Partial<>

constructor(params: Partial<Student>) { ... }

or Pick<> Pick<>

constructor(params: Pick<Student, 'id' | 'name' | 'age'>) { ... }

Another way is to create an interface yourself: 另一种方法是自己创建一个接口:

interface IStudent { id: number, name: string, age?:number }
class Student implements IStudent {
  constructor(params: IStudent) { ... }
}

What is the reason for that? 是什么原因呢?

Basically, {id:1, name: 'Jon'} is not a student, since that object lacks a studentType property. 基本上, {id:1, name: 'Jon'}不是学生,因为该对象缺少studentType属性。 This seems obvious and idiotic but makes sense, since typescript cannot know wether you're gonna rely on that property of the argument or not. 这似乎很明显而且很愚蠢,但是很有意义,因为打字稿无法知道您是否要依赖该参数的属性。

In your constructor, you just call Object.assign and let it go. 在构造函数中,只需调用Object.assign并放手即可。 But you could be calling some function that actually relies on the argument having that property, which could led to a runtime error if not pointed out by typescript. 但是您可能正在调用实际上依赖于具有该属性的参数的某些函数,如果打字稿未指出,则可能导致运行时错误。

and how can I solve it? 以及我该如何解决?

Well, there are several answers already. 好吧,已经有几个答案了。 I would just type the constructor parameter properly. 我只需要正确输入构造函数参数即可。 If you expect an object that has id, name and/or age I would type it accordingly: 如果您希望对象具有ID,名称和/或年龄,则可以相应地输入:


export class Student {
  id: number;
  name: string;
  age?:number;

  get studentType():string {
    return 'fullTime'
  }

  constructor(params: {id: number, name: string, age?: number}) {
    Object.assign(this, params);
  }
}

const student = new Student({id:1, name: 'Jon'}); //ts error here

This is because you are giving the type in constructor as Student. 这是因为您将构造函数中的类型指定为Student。 This can be done: 可以这样做:

export class Student {
  id: number;
  name: string;
  age?: number;

constructor(id:number, name:string,age?:number) {
    this.age = age;
    this.name = name;
    this.id = id;
}

  get studentType():string {
    return 'fullTime'
  }

}

const student = new Student(1, 'Jon');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM