Rule proposal: no-unsafe-optional-property-assignment

Author: JoshuaKGoldbergCreated Nov 9, 2022Updated Sep 16, 2026
Labelspackage: eslint-pluginenhancement: new plugin ruleaccepting prs

Before You File a Proposal Please Confirm You Have Done The Following...

My proposal is suitable for this project

  • My proposal specifically checks TypeScript syntax, or it proposes a check that requires type information to be accurate.
  • My proposal is not a "formatting rule"; meaning it does not just enforce how code is formatted (whitespace, brace placement, etc).
  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Description

From https://github.com/danielnixon/eslint-plugin-total-functions:

Optional properties (those with a ? after their name) interact badly with TypeScript's structural type system in a way that can lead to unsoundness. ... This rule bans assignment from one type to another, if:

  • the destination type has an optional property, and
  • the source type has no matching property (either optional or otherwise).

Note that in order to take the function in here, we'll need to include the fixes proposed in https://github.com/danielnixon/eslint-plugin-total-functions/issues/83.

Fail Cases

typescript
type Foo = { readonly foo: string };
type Bar = Foo & { readonly bar?: () => unknown };

const thing = { foo: "foo", bar: "bar" };
const foo: Foo = thing;
const bar: Bar = foo;

if (bar.bar !== undefined) {
    bar.bar(); // explodes at runtime
}

Pass Cases

typescript
type Foo = { readonly foo: string };
type Bar = Foo & { readonly bar?: () => unknown };

const thing = { foo: "foo", bar: "bar" };
const foo: Foo = thing;
const bar = foo;

// @ts-expect-error
if (bar.bar !== undefined) {
// @ts-expect-error
    bar.bar(); // explodes, but now we know!
}

Additional Info

Forking conversation out from https://github.com/danielnixon/eslint-plugin-total-functions/issues/665.

Source: typescript-eslint/typescript-eslint