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

Fix for "Outlier case in Excess Property detection in Union (a case that is -more- strict than it should be)" #44856 #49004

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

craigphicks
Copy link

@craigphicks craigphicks commented May 6, 2022

Changes to be committed:
modified: src/compiler/checker.ts
new file: tests/baselines/reference/_44856.js
new file: tests/baselines/reference/_44856.symbols
new file: tests/baselines/reference/_44856.types
new file: tests/cases/compiler/_44856.ts

  • fix for issue Outlier case in Excess Property detection in Union (a case that is -more- strict than it should be) #44856

  • minor modifications to checker.ts

    • Preexisting algorithm:

      • In the case of checking for excess properties being assigned to a union, the logic forks:
        • If there is an index in the union whose type qualifies it as discriminant index, then don't allow excess properties (roughly)
        • otherwise, allow excess properites which satisfy some member of the union
    • Change:

      • Don't consider an index with a boolean type to qualify for being a discriminant index.
  • Before:

    • In src/compiler/checker.ts, in the function createUnionOrIntersectionProperty the preexisting code is
if ((isLiteralType(type) || isPatternLiteralType(type) || type === uniqueLiteralType) {
        checkFlags |= CheckFlags.HasLiteralType;
    }
  • isLiteralType(type) returns true for a boolean type, and setting checkFlags |= CheckFlags.HasLiteralType results in a higher up decision to qualify the corresponding index as a discriminated index.

  • After:

if ((isLiteralType(type) &&
        (!fromIsDiscriminantProperty || !(type.flags & TypeFlags.Boolean && type.flags & TypeFlags.Union)))
    || isPatternLiteralType(type) || type === uniqueLiteralType) {
    checkFlags |= CheckFlags.HasLiteralType;
}
  • the fromIsDiscriminantProperty is to provide the context in which createUnionOrIntersectionProperty.
  • That is necessary because createUnionOrIntersectionProperty is called in other contexts that require the existing behavior.
    • Here is one such scenario from objectSpread.ts
function f<T, U>(t: T, u: U) {
    return { ...t, ...u, id: 'id' }
}
let overwriteId: { id: string, a: number, c: number, d: string } =
    f({ a: 1, id: true }, { c: 1, d: 'no' })
  • Without introducing the condition fromIsDiscriminantProperty, overwriteId would have type never.

Fixes #44856

 Changes to be committed:
        modified:   src/compiler/checker.ts
        new file:   tests/baselines/reference/_44856.js
        new file:   tests/baselines/reference/_44856.symbols
        new file:   tests/baselines/reference/_44856.types
        new file:   tests/cases/compiler/_44856.ts

- fix for issue microsoft#44856

- minor modifications to checker.ts

  - Preexisting algorithm:
    - In the case of checking for excess properties being assigned to a union, the logic forks:
      - If there is an index in the union whose type qualifies it as discriminant index, then don't allow excess properties (roughly)
      - otherwise, allow excess properites which satisfy some member of the union

  - Change:
    - Don't consider an index with a boolean type to qualify for being a discriminant index.

- Before:

  - In *src/compiler/checker.ts*, in the function `createUnionOrIntersectionProperty` the preexisting code is

```
if ((isLiteralType(type) || isPatternLiteralType(type) || type === uniqueLiteralType) {
        checkFlags |= CheckFlags.HasLiteralType;
    }
```
  - `isLiteralType(type)` returns true for a boolean type, and setting `checkFlags |= CheckFlags.HasLiteralType` results in a higher up decision to qualify the corresponding index as a discriminated index.

- After:
```
if ((isLiteralType(type) &&
        (!fromIsDiscriminantProperty || !(type.flags & TypeFlags.Boolean && type.flags & TypeFlags.Union)))
    || isPatternLiteralType(type) || type === uniqueLiteralType) {
    checkFlags |= CheckFlags.HasLiteralType;
}
```

- the `fromIsDiscriminantProperty` is to provide the context in which `createUnionOrIntersectionProperty`.
- That is necessary because `createUnionOrIntersectionProperty` is called in other contexts that require the existing behavior.
  - Here is one such scenario from `objectSpread.ts`
```
function f<T, U>(t: T, u: U) {
    return { ...t, ...u, id: 'id' }
}
let overwriteId: { id: string, a: number, c: number, d: string } =
    f({ a: 1, id: true }, { c: 1, d: 'no' })
```
  - Without introducing the condition `fromIsDiscriminantProperty`, overwriteId would have type never.
@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label May 6, 2022
@typescript-bot
Copy link
Collaborator

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

@craigphicks craigphicks changed the title On branch tsmainb/main/44856 Fix for "Outlier case in Excess Property detection in Union (a case that is -more- strict than it should be)" #44856 May 6, 2022
@typescript-bot typescript-bot added For Backlog Bug PRs that fix a backlog bug and removed For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels May 16, 2022
@sandersn sandersn self-assigned this May 16, 2022
@sandersn sandersn requested review from gabritto and sandersn May 16, 2022 22:08
@sandersn
Copy link
Member

sandersn commented Jun 3, 2022

@typescript-bot run dt
@typescript-bot user test this inline

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 3, 2022

Heya @sandersn, I've started to run the diff-based community code test suite on this PR at 78b9245. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 3, 2022

Heya @sandersn, I've started to run the parallelized Definitely Typed test suite on this PR at 78b9245. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

@sandersn
Great news! no new errors were found between main..refs/pull/49004/merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Status: Waiting on reviewers
Development

Successfully merging this pull request may close these issues.

Outlier case in Excess Property detection in Union (a case that is -more- strict than it should be)
3 participants