Skip to content
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

[Question] Parse generic type #810

Closed
GrandSchtroumpf opened this issue May 3, 2020 · 3 comments
Closed

[Question] Parse generic type #810

GrandSchtroumpf opened this issue May 3, 2020 · 3 comments
Labels

Comments

@GrandSchtroumpf
Copy link

GrandSchtroumpf commented May 3, 2020

Hello,
I would like to extract the value "[button]" of the generic type below for example:

type Component<type, selector> = type;
definition class MyComponent {
  static selector: Component<string, '[button]'>;
}

I did :

const type = source.getClass('MyComponent').geStaticProperty('selector').getType();
type.getTypeArguments().map(a => a.getText()); // [ 'string' ]

It looks like getTypeArguments returns the value returned by the type and not the text.
Unfortunately I cannot use type.getText() and string manipulation because the realworld usecase is too complex.

I was looking for something like type.isGeneric() ? type.getGeneric() : [] but did find anything that looks like that.
Thanks for the help :)

@dsherret
Copy link
Owner

dsherret commented May 3, 2020

@GrandSchtroumpf I get the following output instead:

type.getTypeArguments().map(a => a.getText()); // []

What's going on here is the TS compiler is "interning" the type to string. Try doing type.getText() and you will see it's a string. That's done for performance reasons in the compiler (I wish there was a way to disable it)... see this answer from the TypeScript team.

In this scenario, instead of getting the type you can get the type node. Here's an example:

const project = new Project({ useInMemoryFileSystem: true });

const file = project.createSourceFile("file.ts", `type Component<type, selector> = type;
definition class MyComponent {
  static selector: Component<string, '[button]'>;
}`);

// Using https://ts-ast-viewer.com can be useful to figure out what these nodes are...
// You can also use the functions like `Node.isTypeReferenceNode(node)` to check
// if a node is of a certain kind.
const propertyDec = file.getClassOrThrow('MyComponent')
    .getStaticPropertyOrThrow('selector') as PropertyDeclaration;
const typeNode = propertyDec.getTypeNodeOrThrow() as TypeReferenceNode;

console.log(typeNode.getTypeArguments().map(a => a.getText())); // ['string', "'[button]'"]

@GrandSchtroumpf
Copy link
Author

Amazing, thanks a lot !! So many kind of nodes ^^.
Why using TypeNode would work better than getType ?

@dsherret
Copy link
Owner

dsherret commented May 3, 2020

It's a common source of confusion due to somewhat bad naming, but I'm not sure what would be better. getType() returns the type from the type checker (shown in purple in the image below) and getTypeNode() returns the node from the AST (shown in blue).

image

@dsherret dsherret reopened this Apr 3, 2021
@dsherret dsherret closed this as completed Apr 3, 2021
Repository owner locked and limited conversation to collaborators Apr 3, 2021
Repository owner unlocked this conversation Apr 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants