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

exported terms typed to a type alias do not reference type index entry #41

Open
jasonkuhrt opened this issue Nov 8, 2020 · 5 comments · May be fixed by #44
Open

exported terms typed to a type alias do not reference type index entry #41

jasonkuhrt opened this issue Nov 8, 2020 · 5 comments · May be fixed by #44
Labels
needs/upstream An upstream component needs to be updated first pkg/extractor type/bug Something is not working the way it should

Comments

@jasonkuhrt
Copy link
Collaborator

jasonkuhrt commented Nov 8, 2020

The foo named export (term level) should use a type index reference.

export type Foo = string

export const foo: Foo = 'bar'
{
  "modules": [
    {
      "kind": "module",
      "mainExport": null,
      "namedExports": [
        {
          "kind": "export",
          "name": "Foo",
          "type": {
            "kind": "typeIndexRef",
            "link": "(test).Foo"
          },
          "isType": true,
          "isTerm": false
        },
        {
          "kind": "export",
          "name": "foo",
          "type": {
            "kind": "primitive",
            "type": "string"
          },
          "isType": false,
          "isTerm": true
        }
      ],
      "name": "test",
      "tsdoc": null,
      "path": "/src/test",
      "isMain": false,
      "location": {
        "absoluteFilePath": "/Users/jasonkuhrt/projects/prisma-labs/tydoc/src/test.ts"
      }
    }
  ],
  "typeIndex": {
    "(test).Foo": {
      "kind": "alias",
      "name": "Foo",
      "raw": {
        "nodeFullText": "export type Foo = string",
        "nodeText": "export type Foo = string",
        "typeText": "string"
      },
      "tsdoc": null,
      "type": {
        "kind": "primitive",
        "type": "string"
      }
    }
  }
}
@jasonkuhrt jasonkuhrt added type/bug Something is not working the way it should pkg/extractor labels Nov 8, 2020
@jasonkuhrt jasonkuhrt changed the title exported type alias doesn't reference type index entry exported terms typed to a type alias do not reference type index entry Nov 9, 2020
@jasonkuhrt
Copy link
Collaborator Author

I made some progress. I understand now that we can get to the type reference from a variable declaration. But I don't know where to go from here to get back to the type alias declaration node.

I guess what we want is a function that given a variable declaration returns the type declaration that it references.

image

Asking for help here https://stackoverflow.com/questions/64745962/use-typescript-compiler-api-to-get-the-type-alias-declaration-node-from-a-type-r.

@jasonkuhrt
Copy link
Collaborator Author

Heya @dsherret, if you happen to have time/be interested in this, your opinion/ideas would be most welcome!

@dsherret
Copy link

dsherret commented Nov 9, 2020

Answered here. Annoyingly, the ts compiler interns these types for performance reasons so that Foo -> string.

@jasonkuhrt
Copy link
Collaborator Author

Thanks @dsherret!

It seems what Tydoc should do right now then is when a type is "interned" warn the developer of the situation, briefly explaining the limitation. Detecting this would be a matter:

  1. Find a variable declaration whose type is a primitive
  2. Check if there is a type reference node on the variable declaration
  3. If there is, warn

This is quite specific. But its a base we could expand with more cases over time.

Another solution is that given the type reference name, we could manually search the AST for its source, traversing until a declaration is found. In the same case it would be a type declaration in the same lexical block. In a complex case it might be a type import etc. When to trigger this behaviour would be the same trigger as when to attempt the warning. This approach might have performance consequences. I'm not sure how complex it would be to implement.

@dsherret shared some interesting links in his StackOverflow answer:

  1. Should the compiler api resolve certain equivalent types to the first encountered one? microsoft/TypeScript#28197
  2. Why does the ts type checker return structurally equivalent types as the first one requested? dsherret/ts-morph#480
  3. How to detect type alias correctly dsherret/ts-morph#653

Looking at the TS issue it seems that there are a number of interned-type cases:

The specific types we intern today are indexed accesses, unions, and intersections (also reverse mapped types, but only inference can produce those)

Note this list was from 2018, could be outdated now!

@jasonkuhrt
Copy link
Collaborator Author

Left a comment on the TS issue: microsoft/TypeScript#28197 (comment)

@jasonkuhrt jasonkuhrt linked a pull request Nov 9, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs/upstream An upstream component needs to be updated first pkg/extractor type/bug Something is not working the way it should
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants