javascript - 如何在 TypeScript 中实现具有一组值的接口(interface)?

标签 javascript typescript types interface

我正在尝试在这样的类中实现一个接口(interface):

type TLanguage = "TYPE" | "SCRIPT" // Reusable values

interface AnyInterface {
    business: TLanguage
    /** MoreTypes */
}

class Anyclass implements AnyInterface{
    business = "TYPE"
}

这会引发错误:

Property 'business' in type 'Anyclass' is not assignable to the same property in base type 'AnyInterface'. Type 'string' is not assignable to type 'TLanguage'.ts(2416)

预期的行为是,每当我在 TLanguage 范围之外设置任何业务值时,它都会抛出错误...当我将其设置在变量中时,它确实有效:

const anyConst: AnyInterface = {
    business: "TYPE" //✅
    business: "TYPEs" //❌ Type '"TYPEs"' is not assignable to type 'TLanguage'. Did you mean '"TYPE"'?ts(2820)
}

最佳答案

class implements an interface ,它实际上并不影响类的类型。编译器检查类是否与接口(interface)兼容,但它不会使用接口(interface)作为上下文来为类的成员提供类型。这是 TypeScript 的一个痛点,因为人们确实期望发生某种上下文推理。请参阅microsoft/TypeScript#32082以及其中链接的问题以获取更多信息。

当您编写 class Anyclass Implements AnyInterface {...} 时,编译器的行为与您刚刚编写 class Anyclass {...} 的行为非常相似没有实现 AnyInterface。如果您不正确地实现它(或者编译器推断出这一点),您将在 Anyclass 名称上收到错误。

因此,问题是 class Anyclass {business = "TYPE"} 导致 business 从文字类型 "TYPE" 自动扩展> 到 string,因为编译器没有上下文可以执行其他操作,并且 implements AnyInterface 不会改变这一点。


这也意味着您此处的解决方案与您省略 implements AnyInterface 时必须使用的解决方案相同。您可以显式地注释 field 的类型:

class Anyclass implements AnyInterface {
    business: TLanguage = "TYPE"
}

或者你可以使用a const assertion要求编译器不要扩大字符串文字(但这将推断属性类型的 "TYPE" 而不是 TLanguage):

class Anyclass implements AnyInterface {
    business = "TYPE" as const
    // (property) Anyclass2.business: "TYPE"
}

或者你可以做到 a readonly property这也暗示编译器不要加宽(因此它是“TYPE”),并且也不会让您重新分配它:

class Anyclass implements AnyInterface {
    readonly business = "TYPE"
    // (property) Anyclass3.business: "TYPE"
}

Playground link to code

关于javascript - 如何在 TypeScript 中实现具有一组值的接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73169490/

相关文章:

c - stdatomic (C11),关于 _Atomic 类型的三个问题

javascript - AngularJS 中文本框更改时延迟调用函数

typescript - 扩展运算符剥离 typescript 中的类型定义

reactjs - 只需要在范围选择器选择区域 antd 中显示一个月

javascript - 使用 Vite 构建的 React.js 不包含 service-worker.ts

python - 扩展 Python 的 int 类型以仅接受给定范围内的值

types - 将字符串转换为 UTCTime 类型

java - 从 java GWT 代码调用 .js 文件的 Javascript 函数

php - 如果数组中的数据存在,自动生成 JS 变量 PHP/MySQL

javascript - 在 Javascript 中触发 "paste"事件