Skip to content

JSDoc generic return type is treated as any #39531

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

Closed
mpvosseller opened this issue Jul 9, 2020 · 2 comments
Closed

JSDoc generic return type is treated as any #39531

mpvosseller opened this issue Jul 9, 2020 · 2 comments

Comments

@mpvosseller
Copy link

I have a JavaScript file using JSDoc to indicate the return type of a function. The function's return type is a kind of generic (DataContainer<NumberData>) but when I call the method from a TypeScript file the TypeScript compiler treats it as any.

TypeScript Version: 3.9.6

JSDoc, generic, template, any, not working

Code

// data.ts

export interface DataContainer<T> {
  data(): T
}

export interface NumberData {
  value(): number
}
// factory.js

/**
 * @typedef { import('./data').DataContainer } DataContainer
 * @typedef { import('./data').NumberData } NumberData
 */

/**
 * @function
 * @returns { DataContainer<NumberData> }
 */
export default function getDataContainer() {
  const numberData = {
    value: () => 42,
  }
  const dataContainer = {
    data: () => numberData,
  }
  return dataContainer
}
// index.ts

import getDataContainer from './factory'

const container = getDataContainer() // tsc thinks this returns an any but it should be DataContainer<NumberData>
console.log(container.data().value())
console.log(container.someBogusMethod()) // XXX should be tsc compiler error here but container is treated as any so we get a runtime exception instead

Expected behavior:
When compiling this code tsc --allowJs src/* --outDir build/ we expect the TypeScript compiler to give an error at container.someBogusMethod() since DataContainer<NumberData> has no method named someBogusMethod.

Actual behavior:
The build works because it is incorrectly treating container as an any.
This results in a runtime exception when we run it with node build/index.js

Playground Link:

Related Issues:
#26883

@awerlogus
Copy link

Try

/**
 * @template T
 * @typedef {import('./data').DataContainer<T>} DataContainer
 */

@mpvosseller
Copy link
Author

Ah! Thank you. Like you suggested I needed to import DataContainer with the template <T>. I also needed to break out the NumberData typedef into it's own JSDoc comment which I didn't realize. This works:

/**
 * @template T
 * @typedef { import('./data').DataContainer<T> } DataContainer
 */

/**
 * @typedef { import('./data').NumberData } NumberData
 */

/**
 * @function
 * @returns { DataContainer<NumberData> }
 */
export default function getDataContainer() {
  const numberData = {
    value: () => 42,
  }
  const dataContainer = {
    data: () => numberData,
  }
  return dataContainer
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants