我正在尝试在这样的类中实现一个接口(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"
}
关于javascript - 如何在 TypeScript 中实现具有一组值的接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73169490/