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

时间:2019-06-13 16:42:06

标签: javascript typescript

我有此代码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

我收到以下错误

  

“ {{id:number;名称:字符串; }”不能分配给“学生”类型的参数。     类型'{id:number;缺少属性'studentType'。名称:字符串; }'。

studentType是仅获取属性,无法下注设置。

这是什么原因,我该如何解决?

ps。 (我不想像studentType?那样将其设置为可空值或将其转换为一个函数)

4 个答案:

答案 0 :(得分:1)

字母/设置器与常规属性完全一样,这就是为什么Typescript无法区分getter /设置器和常规属性。不过,您可以将所有属性设置为可选,从而可以省略studentType

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

但是现在也可以省略其他属性(例如name)。为了提高类型安全性,您可以引入其他接口:

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

答案 1 :(得分:1)

在TypeScript中,这是一个更具争议性的话题。 对于类,TypeScript将类的整体形状视为类型。

这包括私有变量和方法,在这种情况下,还包括getter / setter。

您的问题的一种解决方案是您可以使用Partial<>

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

Pick<>

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

另一种方法是自己创建一个接口:

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

答案 2 :(得分:1)

  

这是什么原因?

基本上,{id:1, name: 'Jon'}不是学生,因为该对象缺少studentType属性。这似乎很明显而且很愚蠢,但是很有意义,因为打字稿无法知道您是否要依赖该参数的属性。

在构造函数中,您只需调用Object.assign并放手即可。但是您可能正在调用实际上依赖于具有该属性的参数的某些函数,如果打字稿未指出,则可能导致运行时错误。

  

该如何解决?

嗯,已经有几个答案了。我只需要正确输入构造函数参数即可。如果您希望对象具有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

答案 3 :(得分:0)

这是因为您在构造函数中将类型指定为Student。 可以这样做:

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');