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(compiler-cli): ensure literal types are retained when strictNullInputTypes is disabled #38305

Closed
wants to merge 1 commit into from

Conversation

JoostK
Copy link
Member

@JoostK JoostK commented Jul 30, 2020

Consider the NgModel directive which has the ngModelOptions input:

class NgModel {
  @Input() ngModelOptions: { updateOn: 'blur'|'change'|'submit' };
}

In a template this may be set using an object literal as follows:

<input ngModel [ngModelOptions]="{updateOn: 'blur'}">

This assignment should be accepted, as the object's type aligns with the
ngModelOptions input in NgModel. However, if the strictNullInputTypes
option is disabled this assignment would inadvertently produce an error:

Type '{ updateOn: string; }' is not assignable to type '{ updateOn: "blur"|"change"|"submit"; }'.
  Types of property 'updateOn' are incompatible.
    Type 'string' is not assignable to type '"blur"|"change"|"submit"'

This is due to the 'blur' value being inferred to be of type string
instead of retaining its literal type. The non-null assertion operator
that is automatically inserted for input binding assignments when
strictNullInputTypes is disabled inhibits TypeScript from inferring
the string value as its literal type.

This commit fixes the issue by omitting the insertion of the non-null
operator for object literals and array literals.

@JoostK JoostK added type: bug/fix freq1: low severity3: broken target: patch This PR is targeted for the next patch release area: compiler Issues related to `ngc`, Angular's template compiler labels Jul 30, 2020
@ngbot ngbot bot modified the milestone: needsTriage Jul 30, 2020
@JoostK JoostK added target: major This PR is targeted for the next major release and removed target: patch This PR is targeted for the next patch release labels Aug 11, 2020
@JoostK JoostK force-pushed the ttc/literal-types branch 2 times, most recently from 525c749 to 27a83ad Compare November 25, 2020 21:10
@JoostK JoostK marked this pull request as ready for review November 25, 2020 21:37
@JoostK JoostK added the action: review The PR is still awaiting reviews from at least one requested reviewer label Nov 25, 2020
@JoostK JoostK requested a review from alxhub November 25, 2020 21:37
@pullapprove pullapprove bot removed the area: compiler Issues related to `ngc`, Angular's template compiler label Dec 9, 2020
@ngbot ngbot bot removed this from the needsTriage milestone Dec 9, 2020
@pullapprove pullapprove bot added the area: compiler Issues related to `ngc`, Angular's template compiler label Dec 10, 2020
@ngbot ngbot bot added this to the Backlog milestone Dec 10, 2020
@JoostK JoostK removed the action: review The PR is still awaiting reviews from at least one requested reviewer label May 4, 2021
…InputTypes` is disabled

Consider the `NgModel` directive which has the `ngModelOptions` input:

```ts
class NgModel {
  @input() ngModelOptions: { updateOn: 'blur'|'change'|'submit' };
}
```

In a template this may be set using an object literal as follows:

```html
<input ngModel [ngModelOptions]="{updateOn: 'blur'}">
```

This assignment should be accepted, as the object's type aligns with the
`ngModelOptions` input in `NgModel`. However, if the `strictNullInputTypes`
option is disabled this assignment would inadvertently produce an error:

```
Type '{ updateOn: string; }' is not assignable to type '{ updateOn: "blur"|"change"|"submit"; }'.
  Types of property 'updateOn' are incompatible.
    Type 'string' is not assignable to type '"blur"|"change"|"submit"'
```

This is due to the `'blur'` value being inferred to be of type `string`
instead of retaining its literal type. The non-null assertion operator
that is automatically inserted for input binding assignments when
`strictNullInputTypes` is disabled inhibits TypeScript from inferring
the string value as its literal type.

This commit fixes the issue by omitting the insertion of the non-null
operator for object literals and array literals.
@JoostK JoostK added target: patch This PR is targeted for the next patch release and removed target: major This PR is targeted for the next major release labels Oct 31, 2021
Copy link
Member

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice commit. Both because it fixes the error, but also because it removes duplication and makes the code easier to understand.

@petebacondarwin petebacondarwin added the action: presubmit The PR is in need of a google3 presubmit label Nov 5, 2021
@petebacondarwin petebacondarwin removed the request for review from alxhub November 5, 2021 10:45
@JoostK JoostK added the action: merge The PR is ready for merge by the caretaker label Nov 5, 2021
@AndrewKushnir
Copy link
Contributor

Presubmit.

@AndrewKushnir AndrewKushnir removed the action: presubmit The PR is in need of a google3 presubmit label Nov 9, 2021
@atscott
Copy link
Contributor

atscott commented Nov 9, 2021

This PR was merged into the repository by commit 2a27447.

atscott pushed a commit that referenced this pull request Nov 9, 2021
…InputTypes` is disabled (#38305)

Consider the `NgModel` directive which has the `ngModelOptions` input:

```ts
class NgModel {
  @input() ngModelOptions: { updateOn: 'blur'|'change'|'submit' };
}
```

In a template this may be set using an object literal as follows:

```html
<input ngModel [ngModelOptions]="{updateOn: 'blur'}">
```

This assignment should be accepted, as the object's type aligns with the
`ngModelOptions` input in `NgModel`. However, if the `strictNullInputTypes`
option is disabled this assignment would inadvertently produce an error:

```
Type '{ updateOn: string; }' is not assignable to type '{ updateOn: "blur"|"change"|"submit"; }'.
  Types of property 'updateOn' are incompatible.
    Type 'string' is not assignable to type '"blur"|"change"|"submit"'
```

This is due to the `'blur'` value being inferred to be of type `string`
instead of retaining its literal type. The non-null assertion operator
that is automatically inserted for input binding assignments when
`strictNullInputTypes` is disabled inhibits TypeScript from inferring
the string value as its literal type.

This commit fixes the issue by omitting the insertion of the non-null
operator for object literals and array literals.

PR Close #38305
@atscott atscott closed this in 2a27447 Nov 9, 2021
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Dec 10, 2021
dimakuba pushed a commit to dimakuba/angular that referenced this pull request Dec 28, 2021
…InputTypes` is disabled (angular#38305)

Consider the `NgModel` directive which has the `ngModelOptions` input:

```ts
class NgModel {
  @input() ngModelOptions: { updateOn: 'blur'|'change'|'submit' };
}
```

In a template this may be set using an object literal as follows:

```html
<input ngModel [ngModelOptions]="{updateOn: 'blur'}">
```

This assignment should be accepted, as the object's type aligns with the
`ngModelOptions` input in `NgModel`. However, if the `strictNullInputTypes`
option is disabled this assignment would inadvertently produce an error:

```
Type '{ updateOn: string; }' is not assignable to type '{ updateOn: "blur"|"change"|"submit"; }'.
  Types of property 'updateOn' are incompatible.
    Type 'string' is not assignable to type '"blur"|"change"|"submit"'
```

This is due to the `'blur'` value being inferred to be of type `string`
instead of retaining its literal type. The non-null assertion operator
that is automatically inserted for input binding assignments when
`strictNullInputTypes` is disabled inhibits TypeScript from inferring
the string value as its literal type.

This commit fixes the issue by omitting the insertion of the non-null
operator for object literals and array literals.

PR Close angular#38305
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: compiler Issues related to `ngc`, Angular's template compiler cla: yes freq1: low target: patch This PR is targeted for the next patch release type: bug/fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants