When a class that implements an interface, the type of the class remains unaffected. While the compiler ensures that the class is compatible with the interface, it does not utilize the interface as a context to provide types to the class members. This lack of contextual inference can be frustrating for TypeScript users who expect otherwise. For more information, refer to microsoft/TypeScript#32082 and related issues.
When you declare
class Anyclass implements AnyInterface {...}
, the behavior of the compiler is similar to if you had only written
class Anyclass {...}
without the
implements AnyInterface
. Incorrect implementation (or when inferred by the compiler) will result in an error associated with the name
Anyclass
.
This leads to the issue where
class Anyclass { business = "TYPE" }
automatically widens
business
from the literal type
"TYPE"
to
string
due to the absence of context within the compiler, and adding
implements AnyInterface
does not alter this behavior.
Consequently, solutions for this problem are identical regardless of whether you include or omit implements AnyInterface
. You could explicitly specify the type of the field:
class Anyclass implements AnyInterface {
business: TLanguage = "TYPE"
}
Alternatively, you could use a const
assertion to prevent the widening of the string literal (although this would infer "TYPE"
instead of TLanguage
for the property type):
class Anyclass implements AnyInterface {
business = "TYPE" as const
// (property) Anyclass2.business: "TYPE"
}
Another approach is to make it a readonly
property, which also indicates to the compiler not to widen the type (keeping it as "TYPE"
) while preventing reassignment:
class Anyclass implements AnyInterface {
readonly business = "TYPE"
// (property) Anyclass3.business: "TYPE"
}
Access the code on Playground