TypeScript 接口可以限制其实现类的属性吗?

Posted

技术标签:

【中文标题】TypeScript 接口可以限制其实现类的属性吗?【英文标题】:Can a TypeScript interface constrain its implementing class's properties? 【发布时间】:2020-06-26 23:22:48 【问题描述】:

我想定义一个类,它可以有任何string 属性键,但具有特定的对应值类型。我尝试了以下方法:

interface MyValue 
  body: string;
  description: string;


interface MyInterface 
  [key: string]: MyValue;


class MyClass implements MyInterface 

我希望以上内容会产生MyClass,其中以下内容有效:

class MyClass implements MyInterface 
  a = 
    body: "lorem ipsum";
    description: "some latin placeholder",
  ;

...以下是无效的:

class MyClass implements MyInterface 
  a = "lorem ipsum";

我得到一个错误:

Class 'MyClass' incorrectly implements interface 'MyInterface'.
  Index signature is missing in type 'MyClass'.

有没有办法在使用类的同时仍然实现上述所需的行为?

谢谢!

【问题讨论】:

这能回答你的问题吗? Can I define a Typescript class which has an index signature? 你可以用索引签名来注释你的类 【参考方案1】:

您不能使用索引签名来执行此操作。如果你的界面有一个索引签名,你的类也需要一个。

您可以使用映射类型将类的所有键(属性和方法)限制为特定类型:

type MyInterface<K extends PropertyKey> = 
  [P in K] : MyValue


class MyClassEmpty implements MyInterface<keyof MyClassEmpty> 

class MyClassGood implements MyInterface<keyof MyClassGood> 
  a = 
    body: "lorem ipsum",
    description: "some latin placeholder",
  ;


class MyClassBad implements MyInterface<keyof MyClassBad> 
  a = "lorem ipsum"; // error


Playground Link

【讨论】:

它没有将字段视为密封的。如果您向aMyGoodClass 添加更多道具,我们看不到任何错误。 @titian-cernicova-dragomir –– 我们如何防止这种情况发生? @HarrySolovay 这是一个不同的问题 IMO,通常类型在 TS 中是开放的,如果您要使用索引签名声明接口,则属性可能有更多字段。 typescriptlang.org/play?#code/… 如果我尝试将额外的字段分配给类型为 MyValue 的变量,我会收到 TypeScript 错误。出于这个原因,我相信它是同一个问题的一部分。我非常感谢这个答案。并感谢您迄今为止提供的巨大帮助。 这似乎是对语言的限制。除非每个字段都指定了 MyValue 类型,否则与继承相关的推断并不重要;由于结构类型,额外的字段没有影响——类型检查器感知到MyValue 的子类,这是有效的。如果有办法解决这个问题并在实现类时实现更高的严格性,那就太好了。 @HarrySolovay 有一些方法可以在这些字段上强制“精确类型”,尽管它们都有缺陷,尽管我相信可以使用一些方法来确保你想要什么。看到这个线程github.com/microsoft/TypeScript/issues/…

以上是关于TypeScript 接口可以限制其实现类的属性吗?的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript--接口

TypeScript教程# 13:接口

TypeScript接口

TypeScript躬行记——接口

TypeScript,面向对象,类、构造函数、继承、抽象类、接口和封装

TS之接口:①属性接口