Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type 'never' incorrectly inferred for mixed primitive type properties assignment with strictNullChecks disabled #59969

Open
heguro opened this issue Sep 14, 2024 · 2 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@heguro
Copy link

heguro commented Sep 14, 2024

🔎 Search Terms

strictNullChecks false assign never

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?strictNullChecks=false&ts=5.6.2#code/C4TwDgpgBA8gRgKygXigbwFBSmATgezAEYB+ALigGdhcBLAOwHMBuLHAsAJnKpoZbZ5CAZh70ArgFs4EXK2xCwAFh4ARAIbAIrAL6sMAegNQAwusrQiFAIIAbW+0KzgtCJSgALdQDdowD9CU6pJ+4NAAFNR0TACUGADG+PTUUABmRChQ4fiIFPAIADRQANYQIBQARIpEFVAAPlBVHJwVMSgAfOhsOQgA2qUgALqZ4vQAJhCpDBBjzFBGUABq6ra0Y92I-WXDqBL2cwvLq2NQAO4B9Lx08cAAcuL2JgHxxe607qkrFhh6GIbGZgsUE4FAAChxnK53F5fFAxrRUqlZBB6MB2LRJLQXLDQJB3JE+Ex6lAJNJZHFEsk0alOJlsrlYIgigNKtVag0miJWh0utgelshiNxpNprN5sYAKK4Ai4M4XK60G73R7PV5Qd5pL4QAB0UAlAA9IDcZlBgPgoDIoN4VmsNn0BjsSQ9bAdJdL8LhdQajVoTmaLdBrcc5SiFUrnU8IC83h8tWxKSkg5l+Q7XUsbSdwrjoBqovxiaSZLg4mwFgB1D3FdQEUbrbAJtE9WmoHpQczoao8Wsi+gzIqKUQUbtTXtjX58xCcAWO4eitNHW0ThBTh2ZPYu8Xp4PnUN58MqqNqjWfWzfbCHDNQCC+S6nLEeKAAAwg+vUNxgYBcSRW4KcuFAAAqYSUBQNDiBAj5FP4+DiIwD4yDCtAenCCJIrglBsBMtgQFoUAptsuj6AsgLQMIYIQv+ULqvQ8S2OIEwWvg-jopi2LQOo4x4YgUZotm+J5kSDQaFoFJJCkqTCHSPR5EyJRlKyHA1MSnLKNyyCdJgS7TkKEwjjM84Zna2m7M6BnbvKe53BGqoxpqp4QD8zBAA

💻 Code

type Obj = {
  prop1?: string;
  prop2?: string;
  prop3?: number;
  prop4?: Date;
};

// Case 1: All properties have the same type (string)
const f1 = (obj: Obj, key: "prop1" | "prop2") => {
  obj[key] = undefined; // Valid
  obj[key] = null; // Valid when strictNullChecks is false
};

// Case 2: Properties have different primitive types (string | number)
const f2 = (obj: Obj, key: "prop1" | "prop3") => {
  obj[key] = undefined; // Error when strictNullChecks is false. Expected to be valid
  obj[key] = null; // Error. Expected to be valid when strictNullChecks is false
  const val = obj[key]; // Valid (type is string | number)

  // Workaround
  const obj2 = obj as {prop1?: undefined, prop3?: undefined};
  obj2[key] = undefined; // Valid
  obj2[key] = null; // Valid when strictNullChecks is false
  // Valid even with `exactOptionalPropertyTypes: true`, though behavior differs
  delete obj[key];
};

// Case 3: Properties include both primitive and object types (string | Date)
const f3 = (obj: Obj, key: "prop1" | "prop4") => {
  obj[key] = undefined; // Valid
  obj[key] = null; // Valid when strictNullChecks is false
};

🙁 Actual behavior

  1. In Case 2, when strictNullChecks is false:

    • Assigning undefined results in an error: "Type 'undefined' is not assignable to type 'never'.(TS2322)"
    • Assigning null always results in an error: "Type 'null' is not assignable to type 'never'.(TS2322)"
  2. The behavior is inconsistent across different combinations of property types.

🙂 Expected behavior

Since all properties in Obj are optional, it should be possible to assign undefined to obj[key] regardless of the strictNullChecks setting, unless exactOptionalPropertyTypes is true (which cannot be used with strictNullChecks: false).

Additionally, when strictNullChecks is false, assigning null should be allowed for all cases.

Additional information about the issue

No response

@MartinJohns
Copy link
Contributor

Since all properties in Obj are optional, it should be possible to assign undefined to obj[key] regardless of the strictNullChecks setting.

That would depend on the exactOptionalPropertyTypes setting.

@heguro
Copy link
Author

heguro commented Sep 14, 2024

That would depend on the exactOptionalPropertyTypes setting.

I didn't know that. However, at least in TypeScript 5.6.2 and 5.7.0-dev.20240914, it seems that strictNullChecks=false and exactOptionalPropertyTypes=true cannot be used together.
image

Edit: Added reference to exactOptionalPropertyTypes in Expected behavior.
Edit 2: Added delete workground, which can be used with exactOptionalPropertyTypes: true.

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Sep 16, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

3 participants