Repository: TypeScript
Issue: Guidance / doc improvements for exactOptionalPropertyTypes for deleting an optional property that cannot be set undefined.
Labels: Suggestion,In Discussion,Domain: Error Messages,Awaiting More Feedback

# Suggestion

Documentation / compiler message improvements surrounding the new `exactOptionalPropertyTypes` flag.
Specifically, guidance surrounding optional properties that have been set and need to be 'deleted'.

## 🔍 Search Terms

`exactOptionalPropertyTypes`
`undefined isn't a number`, `Type 'undefined' is not assignable to type 'number'`

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

I'm very much looking forward to `exactOptionalPropertyTypes` in TS 4.4 :-)

Given the following code, and assuming that `exactOptionalPropertyTypes` is enabled, it is clear that the developer never wants to allow `age === undefined`.

```
interface Person {
    name: string,
    age?: number;
}

let person: Person = {
    name: "Daniel",
    age: 27
};
```
An attempt to set age to undefined will of course give a clear message, easily understood.
```
p.age = undefined;    // Error! undefined isn't a number
```

However, the effectiveness of `exactOptionalPropertyTypes` flag may be undermined if the user is not familiar with the `delete` construct as an alternative to `person.age = undefined`:

```
delete person.age;
```

In my experience it is very rare to see this in 'normal' everyday code, and therefore a reminder about its existence would be welcome in both the docs for `exactOptionalPropertyTypes` and any compiler warning messages. Perhaps the above message `Error! undefined isn't a number` should be more specific if `exactOptionalPropertyTypes` was the reason it was triggered.

Note: I've added this suggestion after first mentioning it in feature pull request https://github.com/microsoft/TypeScript/pull/43947#issuecomment-880258619.

Regarding Daniel's comment in that thread about whether or not using `delete` is a best practice, I would agree that perhaps for a person's age the design should have it as nullable or undefineable - but there are many other situations where you might set a value you later want to undo. 

Reverting the type definition back to `| undefined` would undermine the whole point of this feature - which is to eliminate unwanted iterable undefined properties!

## 📃 Motivating Example

Quick example: Currently I am defining breakpoints in an interactive UI such as:

    type Breakpoint<T> = { mobileS?: T, mobileM?: T, mobileL?: T, tabletS?: T  /* etc*/ }

Clearly if the user adds a `mobileL` breakpoint and then deletes it I would want that gone from the model and not merely set to undefined.

    { mobileS: 'red', mobileL: undefined, desktop: 'blue' }    // [yuk!]

## 💻 Use Cases

Better educated TS users :-)

PS. I realize it's still early days for 4.4, but wanted to raise this after reading the original blog post.