Microsoft/TypeScript

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

Open

#52.042 aperta il 28 dic 2022

Vedi su GitHub
 (4 commenti) (2 reazioni) (0 assegnatari)TypeScript (6726 fork)batch import
BugDomain: JSDocHelp Wanted

Metriche repository

Star
 (48.455 star)
Metriche merge PR
 (Merge medio 6g 17h) (9 PR mergiate in 30 g)

Descrizione

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.

Guida contributor