【问题标题】:TypeScript. Type error when creating new object with spread operator打字稿。使用扩展运算符创建新对象时出现类型错误
【发布时间】:2020-01-31 09:41:55
【问题描述】:
class Todo {
    private _date: Date;
    public name: string;

    constructor(todo: Todo) {
        this._date = todo._date;
        this.name = todo.name;
    }

    get date() { ... }
}
// example
const todos = Agent.fetchTodos();

const modifiedTodos1 = map.todos(todo => new Todo(todo)); // works fine
const modifiedTodos2 = map.todos(todo => new Todo( { ...todo, _date: new Date() } )); // doesn't work

第二行 modifiedTodos2 代码给了我以下错误:property date is missing in type [...]

在我的场景中,我需要使用扩展运算符来扩展 todo 对象,并添加一个额外的道具。但我不确定为什么我会看到这个错误以及如何处理它...... 而且我也不能使用? 运算符使date 成为可选。

非常感谢您提前指出为什么我的方案不起作用以及如何使它起作用!

【问题讨论】:

  • 我认为这个声明 get date() { ... } 限制了其他属性的创建,或者至少将 attr date 设置为必需属性。

标签: javascript typescript types


【解决方案1】:

您尝试做的事情是错误的,因为您没有考虑封装。 _date 是一个私有字段,不应在对象之外访问。你定义了 getter date,使用它。

你不应该使用

this._date = todo._date;

但是

this._date = todo.date;.

这是一个例子:

class Todo {
  private _date: Date;
  public name: string;

  constructor(todo) {
    this._date = todo.date;
    this.name = todo.name;
  }

  get date(): Date {
    return this._date;
  }
}

const todo = new Todo(null);

const modifiedTodos1 = new Todo(todo);

const modifiedTodos2 = new Todo({
  ...todo,
  date: new Date(),
});

另请注意,如果您在构造函数中强烈键入todo,它将不起作用,例如:

  constructor(todo: Todo) {
    this._date = todo.date;
    this.name = todo.name;
  }

因为 typescript 正在等待您未使用扩展运算符提供的 Todo 对象(无日期函数)

为了解决这个问题,我建议您指定一个只包含您的 setter 数据的接口。

interface ITodo {
  date: Date,
  name: string,
}

class Todo {
  private _date: Date;
  public name: string;

  constructor(todo: ITodo) {
    this._date = todo.date;
    this.name = todo.name;
  }

  get date(): Date {
    return this._date;
  }
}

const todo = new Todo(null);

const modifiedTodos1 = new Todo(todo);

const modifiedTodos2 = new Todo({
  ...todo,
  date: new Date(),
});

【讨论】:

    【解决方案2】:

    除了以前的答案。除了接口,你可以使用类型:

    declare type TodoType ={
        name:string,
        date:Date
    }
    class Todo {
        private _date: Date;
        public name: string;
    
        constructor(todo: TodoType) {
            this._date = todo.date;
            this.name = todo.name;
        }
    
        otherBehavior = ()=> {}
    
        get date() { return this._date;}
    }
    
    const toDos:Array<Todo> = [];
    
    const modifiedTodos2 = toDos.map(todo => new Todo( { ...todo, date: new Date() } )); 
    
    

    通过这种方式,您可以向您的Todo 类添加其他行为(属性/方法),而无需在您传递的对象中传递这些以创建Todo 的实例

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 2018-07-25
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多