-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ADTs with inheritance #20144
Comments
This is because, unlike Scala which is nominally typed with the exception of the experimental As you have noted, there is a static error at the call site meaning that type safety is uncompromised.
See the approach outlined in #9163, the pull request introducing the feature.
This can already be done interface Tagged<K extends string> {
kind: K;
}
interface Drawable {
draw(): void;
}
type TaggedDrawableWithId<K extends string> = Tagged<K> & Drawable & {
id: number
}; And interfaces can also extends type aliases interface Pentagon extends TaggedDrawableWithId<'pentagon'> {
points: [number, number, number, number, number];
} Note: questions like these are better asked on Stack Overflow or Gitter. |
@aluanhaddad Thanks for the explanation. I'm a bit confused though:
|
Not a perfect solution but the following will give you an error "near" the declaration: type T = A | B;
interface I { draw(): void; }
function __test_T_is_I(t: T): I { return t; }
class A { draw() {} }
class B {} |
If you want to remove the function so it doesn't exist at runtime, you might alternately write type T = A | B;
interface I { draw(): void; }
type __test_T_is_I<U extends I = T> = {};
class A { draw() {} }
class B {} Or actually, you could inline the constraint like type Shape<S extends I = A | B> = S;
interface I {
draw(): void;
} but whichever variant you go with, I think @andy-ms's suggestion is the right approach. |
@andy-ms Very nice solution, thanks! I think it is also possible to implement it into the language, something like this (with the type T < I = A | B;
interface I { draw(): void; } Is it something the TypeScript team consider adding to the language? |
I do not think these two concepts fit together really.. can you elaborate on the scenario here? and why structural checking is not sufficient at use sites? |
@mhegazy You're probably right about the topics not being a fit, but let me explain with another example. Consider I want to have an Expression hierarchy: Expression = BinaryExpression | UnaryExpression | Literal
class BinaryExpression {
constructor(public left: Expression, public right: Expression) {}
}
class UnaryExpression {
constructor(public expr: Expression) {}
}
class Literal {
constructor(public val: number) {}
} Now consider that I also want my Expression hierarchy also have a I defined the following interface that defines the
My question is that is there a way to restrict the In other words, is there a way to enforce a that all members of a union type have a specific property? In Scala, using case classes I can have such a property and was wondering if it is possible to also get it in TypeScript. |
I understand, but why is not use site sufficient in this case. i.e. passing |
A call site error is not a real problem, and the error message is also very clear indicating which type does not have There are two things, which I would say would be nice, if I could enforce a super type on the union type:
|
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
I'd like to define an ADT and also enforce that all concrete types implement another interface (I know that is not how ADTs are supposed to be used, but since TypeScript is a mixed paradigm language, I'd like to be able to do it the way I'm used to it in Scala). This is an attempt to achieve it:
The problem is that I cannot enforce that all concrete classes implement
Drawable
when defining them:and I only will get an error when actually call
draw()
on aShape
instance.In Scala, for example, I can enforce that all concrete case classes to implement the
Drawable
interface:Is there a way to achieve this in TypeScript?
Is there a plan to allow discriminated union type matching feature with interfaces?
Is there a plan to allow type aliases to extend interfaces?
The text was updated successfully, but these errors were encountered: