-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Generic meta types #3779
Comments
I like the idea, but maybe this can also be solved with type providers (#3136). This would be way more flexible. |
It seems like $Merge would be better described through intersection types: // & not checked in yet but you can use | here to see how it works with unions
type c = typeof a & typeof b; $Args and $RetV look like they're essentially compile time reflection APIs. |
Some of these meta types can have corresponding meta operators: @Lenne231, I'm not familiar with type providers, but a brief look at #3136 made me think that it's an imperative/procedural way of constructing types at compile time, while what I'm suggesting is a declarative way. If this is the case, then type providers is indeed a much more powerful feature. |
Btw, does TS have plans to support nested types: interface DecoratedFunction<F extends (...args) => any> {
(...args): F.ReturnValueType;
tag: number;
} |
A "generic meta type" that creates a subset would also be nice, especially for functions that update data.
|
It seems, that the appropriate place for such "generic meta types" (that would better be called "type expressions" or "computed types") is the .d.ts files. Currently they can contain only static type definitions, but could also contain "dynamic definitions": /// [mytypes.d.ts]
declare module mytypes {
export type BasicType = (a, b) => number;
export type Intersection(a: ObjectLiteral, b: ObjectLiteral) {
const r = new ObjectLiteral;
for (const name of a.members) {
if (name in b.members) {
if (!Type.same(a.members[name], b.members[name]))
throw CompileError(...);
r.members[name] = a.members[name];
}
}
return r;
};
}
/// [sample.ts]
type X = { a: number; b: string };
type Y = { b: string; c: symbol };
type Z = mytypes.Intersection(X, Y); Such computed types could be compiled in some special "compilation context" in which all these /// [mytypes.d.ts]
declare module mytypes {
export type "&" (a: ObjectLiteral, b: ObjectLiteral) {
return Intersection(a, b);
}
} Of course, some of these computed types will be pretty common and will naturally become a part of the standard types library: /// [lib.d.ts]
type "&" (a: ObjectLiteral, b: ObjectLiteral) { ... } This should make it possible to express all fancy constructs that can exist in JS. |
It seems that part of the motivating case could be met by extending
Would then become
Args is harder to see. |
this is already covered by #2710 |
As far as I know, in Flow there are so called "generic meta types" that can operate on other types:
Such "type algebra" would be useful to construct function signatures and interfaces that are hard/impossible to construct with other techniques:
Do you think this would be a useful addition to the type system?
The text was updated successfully, but these errors were encountered: