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