Microsoft/TypeScript

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

Open

#52,042 创建于 2022年12月28日

在 GitHub 查看
 (4 评论) (2 反应) (0 负责人)TypeScript (6,726 fork)batch import
BugDomain: JSDocHelp Wanted

仓库指标

Star
 (48,455 star)
PR 合并指标
 (平均合并 6天 17小时) (30 天内合并 9 个 PR)

描述

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.

贡献者指南