Microsoft/TypeScript

Irregular behavior of equivalent code between `.js` and `.ts`.

Open

#52,042 opened on Dec 28, 2022

View on GitHub
 (4 comments) (2 reactions) (0 assignees)TypeScript (48,455 stars) (6,726 forks)batch import
BugDomain: JSDocHelp Wanted

Description

Bug Report

🔎 Search Terms

JSDoc import, no compile, generic function, checkJs, allowJs, inconsistent behavior

🕗 Version & Regression Information

typescript 4.9.4 both in vscode and in node modules

⏯ Playground Link & 💻 Code

full .ts playground link

The equivalent code with JSDoc type imports, i.e.:

  • ./index.js
/**@type {import("./types").IMemoize}*/
const memoize = (fn) => {
    // some memoization logic
    return (...args) => {
        // some more memoization logic
        return fn(...args)
    }
}; 

/**@type {import("./types").IFn}*/
const fn  =  memoize((args) => {
    return [];
});
  • ./types.ts
export type IMemoize = <
    P extends ISerializableValue[],
    R
>(
    fn : ( ...parameters : P) => R
) => ( ...parameters : P) => R;

type ISerializableValue     = ISerializableReference | ISerializablePrimitive;
type ISerializableReference = ISerializableValue[] | {[x : string] : ISerializableValue};
type ISerializablePrimitive = string | boolean | number | null;

export type IFn = (args: {
    arg1: string;
}) => number[][];
  • ./tsconfig.json
{
    "compilerOptions": {
        "checkJs": true,
        "allowJs": true,
        "noEmit": true,
        "target": "ESNext",
        "module": "ESNext",
        
        "strict": true,
        
        "skipLibCheck": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "moduleResolution": "Node",
        "allowSyntheticDefaultImports": true
    },
    "include": [
        "./**/*.ts",
        "./**/*.js"
    ],
    "exclude": [
        "node_modules",
    ]
}

🙁 Actual behavior

Getting a linting error on fn on index.js :

Argument of type '(args: { arg1: string; }) => never[]' is not assignable to parameter of type '(...parameters: ISerializableValue[]) => never[]'.
  Types of parameters 'args' and 'parameters' are incompatible.
    Type 'ISerializableValue' is not assignable to type '{ arg1: string; }'.
      Type 'null' is not assignable to type '{ arg1: string; }'.ts(2345)

while not in the fn of the playground link.

🙂 Expected behavior

We are dealing with exactly the same concretions and abstractions for both cases:

  1. both abstractions and concretions are written in .ts
  2. only abstractions are written in .ts and only concretions are written in .js. Types are imported in .js from .ts via JSDoc imports.

There should not be any difference in the type checking.

Contributor guide