3 ms·
age?: int Why does it (and ts) put “?” only at a name? I’d expect the above to define an optional key, and (type|undefined) but always existing key, as well as
by wruza 4y ago
age?: int
Why does it (and ts) put “?” only at a name? I’d expect the above to define an optional key, and (type|undefined) but always existing key, as well as an optional argument, to have a type of
age: int?
As a result, an optional key with an optional value would be
age?: int?
Am I missing something?
- dmitriid 4y agoI guess it's because most people think of this as "the property is optional, when it's there, it's of type int".
- wruza 4y agoI can’t test type narrowing right now, but I suspect that (“age” in obj) or a similar hasOwn() etc wouldn’t narrow it to just (type) in neither of these languages. It is correct to write “age?” under your assumption, e.g. for settings objects, but sometimes a property is or must be always there. Maybe the reason is that this distinction creates an unnecessary complexity at matching semi-optional types together, because programs do not usually care about exists/defined distinction.
- Benjamin_Dobell 4y agoBecause `exactOptionalPropertyTypes` was only introduced relatively recently (https://devblogs.microsoft.com/typescript/announcing-typescript-4-4/ https://devblogs.microsoft.com/typescript/announcing-typescr...). Without exact optional properties enabled, the type `{ age?: number }` will accept both `{}` and `{ age: undefined }`. With `exactOptionalPropertyTypes` enabled `{ age: undefined }` is illegal. So `{ age?: number }` does mean the key is optional. If you want optional and supporting undefined then type you're after is `{ age?: undefined | number }`.
- wruza 4y agoThank you, this made it very clear!