vuejs / vue-eslint-parser

The ESLint custom parser for `.vue` files.
MIT License
443 stars 74 forks source link

Add support for `<script setup lang=ts generic="...">` #182

Closed ota-meshi closed 1 year ago

ota-meshi commented 1 year ago

This PR adds support for generic attributes.

The value of the generic attribute is parsed as a new node VGenericExpression.

export interface VGenericExpression extends HasLocation, HasParent {
    type: "VGenericExpression"
    parent: VExpressionContainer
    params: TSESTree.TSTypeParameterDeclaration["params"]
    rawParams: string[]
}

This change adds a new trick for resolving typescript type information.

When the generic attribute is specified, before passing the code to the script parser, we add virtual code to parse the type information specified by the generic attribute, and then remove it from the AST and scope manager.

e.g.


input:

<script setup lang="ts" generic="T">
const props = defineProps<{ foo: T }>();
</script>

virtual code:

type T = unknown;
const props = defineProps<{ foo: T }>();

input:

<script setup lang="ts" generic="T extends string">
const props = defineProps<{ foo: T }>();
</script>

virtual code:

type T = string;
const props = defineProps<{ foo: T }>();

input:

<script setup lang="ts" generic="T extends Foo, U extends T">
type Foo = number | string;
const props = defineProps<{ foo: T, bar: U }>();
</script>

virtual code:

type T = Foo;
type U = T;
type Foo = number | string;
const props = defineProps<{ foo: T, bar: U }>();
richardtallent-erm commented 1 year ago

Happy to see this is in progress! I upgraded to 3.3 this morning and tried to use generics and started immediately hitting no-def errors.

Noxdor commented 1 year ago

Thank you for your effort, can't wait to have this working and update to 3.3!