Closed CristianPi closed 2 years ago
I don't understand your goal. typeOf<I>
is not a valid syntax since I
is generic. Do you want number
from a I<number>
expression?
@marcj
I want to reflect that generic interface I<T>
to extract the definition:
{ a: T; b: A, c: B }
typeOf<I>
works in the sense that i can obtain the objectLiteral
My problem is:
How do i get the objectLiteral defined on the type declaration { a: T; b: A, c: B }
from a generic like this I<number>
?
I'm building a custom http client and i need to export all used types with all the declarations (classes, interfaces, alias ect.)
I'm using a custom stringifyType
function to do that, the only problem is that i can print a generic I<number>
but not the declaration
interface I<T>{ a: T; b: A, c: B }
Maybe adding a declaration?:Type
to TypeAnnotations
could solve this.
Hope this is more clear,
How do i get the objectLiteral defined on the type declaration { a: T; b: A, c: B } from a generic like this I
?
That's not possible and making it available means a performance hit.
So if you use somewhere in the http stuff the interface I
you had to specify a type argument T, right? At no place should you get { a: T; b: A, c: B }
since generic interface always have to be instantiated. Do you have example code of that http API? I can't imagine that you have somewhere a reference I
without a specified generic type argument.
Also, we can not print declaration. What would you print if the interface is like that?
interface I<T>{
a: T extends string ? 'yes' : 'no';
b: A,
c: B
}
All expressions can not be printed as the information is not always available and neither is there a parser of bytecode to string type expressions.
Also, we can not print declaration. What would you print if the interface is like that?
interface I<T>{ a: T extends string ? 'yes' : 'no'; b: A, c: B }
All expressions can not be printed as the information is not always available and neither is there a parser of bytecode to string type expressions.
Yes i see, this does not work, a= literal "no"
in this case.
In general what i want is something like this
interface I<T>{
a: T;
b: A,
c: B
}
// this print the type
typeToTs<I>() === `
interface I<T>{
a: T;
b: A,
c: B
}
`
// this print the type
typeToTs(resolveTypeDeclaration<I<number>>()) === `
interface I<T>{
a: T;
b: A,
c: B
}
`
With time it should be possible to serialize all expressions, although i'm happy with simple generic interface for now.
adding declaration?:Type to TypeAnnotations
is a performance hit?
const __ΩA = ['T', 'b!e!!'];
const __ΩI = ['T', 'a', () => __ΩA, 'b', () => __ΩB, 'c', 'b!Pe"!4"e"!o#"4$n%4&M'];
const __ΩI2 = ['T', "yes", "no", 'a', () => __ΩA, 'b', () => __ΩB, 'c', 'l4."R.#RPe#!&qk#&QRb!PPde#!p)4$e"!o%"4&n\'4(M'];
const __ΩB = [() => __ΩA, 'a', 'P)o!"4"M'];
// @ts-ignore
const ia = (0, type_1.typeOf)([], [() => __ΩI2, 'n!']);
const ib = (0, type_1.typeOf)([], [() => __ΩI, '\'o!"']); // __ΩI the interface "declaration"
The information is already there.
No, the information is not there automatically. You'd have to run I
through the VM without type arguments to get a computed I
with T
in place and wrongly resolved type expressions.
With time it should be possible to serialize all expressions
What do you mean? We do not plan to allow to serialise declarations. Stringifying type declarations is an entirely different thing compared to runtime type computation. The runtime type system is not meant to get back the declaration syntax of your TS source code.
It would be useful for all sort or things like: https://github.com/hanayashiki/deepkit-openapi
The alternative is to use another runtime like typescript-rtti, but it's an overkill to use one runtime for validation and another to get a full type reflection.
It would be useful for all sort or things like: https://github.com/hanayashiki/deepkit-openapi
No, that works perfectly fine without having declaration/source code information available in runtime. I don't think you ever need the declaration source code of an interface or in other words the unresolved uninstantiated type in any http library or in any use-case. You still haven't shown a concrete use-case. deepkit-openapi and Deepkit API console do not need it and everything works fine.
The alternative is to use another runtime like typescript-rtti
No, since it doesn't support that either. Also typescript-rtti's emitted JS is 10x bigger.
I'm building a custom http client and i need to export all used types with all the declarations (classes, interfaces, alias ect.)
This is very ambiguous, but let's assume you mean for example that you have code like that
interface I<T>{
a: T;
}
interface HttpRoutes {
route1(): I<string>
}
Does your http client library want to export that I<T>
because it is used in a HTTP route? If so, then that's wrong and an information that is not valuable. In reality only a very tiny subset is used, namely I<string>
. This I<string>
is what you should export, anything else is a wrong type (in fact it's not a type, it's a type expression).
@marcj
Yes it's mostly for readability
interface I<T>{
a: T;
}
interface HttpRoutes {
route1(): I<string>
}
output without generic "support"
interface HttpRoutes {
route1(): {a:string}
}
It's not important anymore, i managed to export aliases and interfaces (non generic type) Generics are printed as is. Thanks for the great support! :100:
About typescript-rtti i made a pull to support generic aliases/interfaces, but yes, i think this project is superior, the size it's a deal breaker for the front-end.
I need to resolve the type declaration from a generic (ex. I\<number> -> I\<T>) any way to do that?