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

JSDoc template constraint ignored when noImplicitAny #47694

Closed
mhofman opened this issue Feb 2, 2022 · 3 comments
Closed

JSDoc template constraint ignored when noImplicitAny #47694

mhofman opened this issue Feb 2, 2022 · 3 comments
Assignees
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@mhofman
Copy link

mhofman commented Feb 2, 2022

Bug Report

πŸ”Ž Search Terms

jsdoc template constraint unknown

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ

Tested all recent versions and nightly (4.6)

⏯ Playground Link

Playground Link: Provided

πŸ’» Code

/**
 * @template {object} T
 * @param {string} detail
 * @param {T} obj
 * @returns {T}
 */
function foo(detail, obj =/** @type {T} */ ({})) {
  if ("bar" in obj) {
    console.log(obj.bar);
  }
  return obj;
}
Compiler Options
{
  "compilerOptions": {
    "strictNullChecks": true,
    "downlevelIteration": true,
    "checkJs": true,
    "allowJs": true,
    "declaration": true,
    "target": "ES2017",
    "module": "ESNext",
    "moduleResolution": "node"
  }
}

πŸ™ Actual / πŸ™‚Expected behavior

T should extend object, but when noImplicitAny: false, type T extends unknown (toggle in config to see correct extends object)

This seem to be a JSDoc only behavior as the equivalent TS code with noImplicitAny: false

function foo<T extends object>(detail: string, obj: T = ({} as T)) {
  if ("bar" in obj) {
    console.log(obj.bar);
  }
  return obj;
}
Output
function foo(detail, obj = {}) {
    if ("bar" in obj) {
        console.log(obj.bar);
    }
    return obj;
}
Compiler Options
{
  "compilerOptions": {
    "strictNullChecks": true,
    "downlevelIteration": true,
    "declaration": true,
    "target": "ES2017",
    "module": "ESNext",
    "moduleResolution": "node"
  }
}

Playground Link: Provided

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Feb 3, 2022
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.7.0 milestone Feb 3, 2022
@sandersn sandersn added Design Limitation Constraints of the existing architecture prevent this from being fixed and removed Needs Investigation This issue needs a team member to investigate its status. labels Feb 4, 2022
@sandersn
Copy link
Member

sandersn commented Feb 5, 2022

object in JSDoc means any when noImplicitAny: false. That's the setting that we expect people will use when first adding old JS to a compilation, and object is frequently used to mean "basically any type" in non-checked JSDoc. Setting noImplicitAny: true is a signal that you want stricter TS semantics applied to JS.

You'll get the same T extends unknown in TS when you write T extends any. That's because any doesn't behave soundly in assignability checks that use the constraint of a type parameter.

@sandersn sandersn closed this as completed Feb 5, 2022
@mhofman
Copy link
Author

mhofman commented Feb 5, 2022

object in JSDoc means any when noImplicitAny: false

That's a surprising and fairly significant limitation I haven't seen documented anywhere! For code that cannot transition to noImplicitAny yet, is there any way to get the behavior of object so that code can be gradually made stricter?

@sandersn
Copy link
Member

sandersn commented Feb 7, 2022

... I haven't seen documented anywhere!

Hm, I thought that it was, but it's not. Historically, the object type was introduced about the same time as checkJs, and it was a niche, new feature for a couple of years.

The workaround I have suggested before is to alias object in Typescript and refer to the alias in Javacript file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants