Closed
Description
Bug Report
This was the one type error I got when I updated my project from TS 4.1 → 4.2. It's a false positive so I figured I'd file an issue in case others run into it as well. I assume this is considered an acceptable loss from this change in the release notes, but it is a false positive and regression from 4.1 nonetheless!
🔎 Search Terms
- object spread undefined 4.2
Possibly related to #13195
🕗 Version & Regression Information
- This changed between versions 4.1.5 and 4.2.2
⏯ Playground Link
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2017",
"jsx": "React",
"module": "ESNext"
}
}
Playground Link: Provided
💻 Code
const param2 = Math.random() < 0.5 ? 'value2' : null;
const obj = {
param1: 'value1',
...(param2 ? {param2} : {})
};
const query = Object.entries(obj).map(
([k, v]) => `${k}=${encodeURIComponent(v)}`
// ~
// Argument of type 'string | undefined' is not assignable to parameter of type 'string | number | boolean'.
// Type 'undefined' is not assignable to type 'string | number | boolean'.(2345)
).join('&');
Output
"use strict";
const param2 = Math.random() < 0.5 ? 'value2' : null;
const obj = Object.assign({ param1: 'value1' }, (param2 ? { param2 } : {}));
const query = Object.entries(obj).map(([k, v]) => `${k}=${encodeURIComponent(v)}`
// ~
// Argument of type 'string | undefined' is not assignable to parameter of type 'string | number | boolean'.
// Type 'undefined' is not assignable to type 'string | number | boolean'.(2345)
).join('&');
🙁 Actual behavior
TypeScript says that v
can be undefined
, which it cannot. This leads to the type error in the call to encodeURIComponent
.
🙂 Expected behavior
v
can never be undefined
at runtime, so the error is a false positive. This was not an error in TypeScript 4.1.
The root cause is that the type of obj
is inferred as
const obj: {
param2?: string | undefined;
param1: string;
}
whereas in TS 4.1 the same inferred type shows up as:
const obj: {
param2?: string;
param1: string;
}