typescript 是否可以定义一个类来实现接口而不需要实现?

kulphzqa  于 2023-04-22  发布在  TypeScript
关注(0)|答案(2)|浏览(185)

有没有可能定义一个类,它有接口变量而没有实现TypeScript?
例如:

interface ITask {
  id: number;
  title: string;
}

class Task implements ITask {
  // without implementation
}

上面的代码会导致这样的错误:

Type 'Task' is missing the following properties from type 'Task', ...

我也尝试了下面的代码,但它也导致了一个错误:

class Task extends ITask {
  // without implementation
}
TypeError: Class extends value undefined is not a constructor or null

我问这个问题是因为我想从接口自动生成类,而不需要改变任何变量,我不想复制粘贴所有的变量。

tyu7yeag

tyu7yeag1#

--strict编译器选项套件为您提供了很多类型安全。(如果你没有使用它,那么你应该使用它)听起来像是你在试图规避其中的一些并且我不清楚你为什么要这样做如果你让编译器相信这个类已经实现了接口而实际上并没有这样做你所做的只是抑制编译器警告,这意味着防止出现运行时错误。就目前而言,下面的代码会产生编译器警告:

const t: ITask = new Task(); // error here
t.id.toFixed(2);

这是一件好事,因为在运行时,t.id将是undefined,所以t.id.toFixed()将抛出异常。如果您强制Task implements ITask工作,那么您将不会收到编译器警告,但您仍然会收到运行时错误。
如果你真的想这样做,你可以使用declaration merging来重新打开Task的示例接口,并让它扩展ITask

interface Task extends ITask { } // merging
class Task implements ITask {
}

现在没有错误了,但你当然会遇到同样的问题:

const t = new Task();
t.id.toFixed() // compiles without error

如果你想安全起见,你可以使用Partial<T>实用程序类型让Task实现Partial<ITask>,使ITask的属性成为可选的:

interface Task extends Partial<ITask> { }
class Task implements Partial<ITask> {
}

现在,编译器将期望Task * 可能 * 具有这些字段,但您需要在使用它们之前检查它们是否无效,例如使用可选的链接操作符(?.):

const t = new Task();
t.id.toFixed() // compiler error now
t.id?.toFixed(); // okay

Playground链接到代码

ruarlubt

ruarlubt2#

您可以使用这种方法

interface IUser {
  name: string;
  email: string;
  phone: string;
}

interface User extends IUser {}
class User {
  constructor(user: IUser) {
    Object.assign(this, user);
  }

  getFullName() {
    return this.name;
  }
}

const userData: IUser = {
  email: "john@xyz.com",
  phone: "1234567890",
  name: "John Doe",
};

const user = new User(userData);
console.log(user.email); // john@xyz.com
console.log(user.getFullName()); // John Doe

相关问题