简体   繁体   中英

Function argument types are not properly check when assigning functions

I ran into a weird interaction in TypeScript:

type Vector2 = { x: number; y: number };
type Vector3 = { x: number; y: number; z: number };

type Takes2 = (vec: Vector2) => void;
type Takes3 = (vec: Vector3) => void;

let f2: Takes2 = (vec) => console.log(vec.x + vec.y);
let f3: Takes3 = (vec) => console.log(vec.x + vec.y + vec.z);

// This makes sence - we call f2 with Vector3, so the "z" prop is going to be ignored
f3 = f2;
f3({ x: 1, y: 2, z: 5 }); // prints 3 (1 + 2)

// This makes no sence - we call f3 with Vector2, so we read undefined when we read vec.z
f2 = f3;
f2({ x: 1, y: 2 }); // prints NaN! (1 + 2 + undefined)

It looks like when one function is assigned to another variable (or passed as an argument I guess), TypeScript only checks if the types are "one way compatible" (one of the arguments can be assigned to the other), but doesn't bother checking if the direction in which the argument types are compatible in matches with the direction of the function assignment.

Is it always like this? Or is a compiler option that can be toggled?

TypeScript version: 4.4.4 tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "downlevelIteration": true,
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    // "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    // "module": "commonjs",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    // "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "baseUrl": ".",
    "paths": {
      "*": ["./src/*"]
    }
  },
  "types": ["forge-viewer"],
  "include": ["src"]
}

The flag you are looking for is strictFunctionTypes .

I noted in your config that you've commented out "strict": true . Had you left strict mode on (this is recommended), then strictFunctionTypes would have been included and you'd have gotten a compile error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM