microsoft/TypeScript

bug: optional properties and assignability to empty values (e.g. `never`)

KiaraGrouwstra opened this issue · 2 comments

Based on a comment:

TypeScript Version: 2.5.0-dev.20170626

Code

type T = { a: never; b?: 1; c: 1; };
const v: T = { c: 1 };
// Property 'a' is missing in type '{ c: 1; }'.

Expected behavior:
Probably no error, since requiring never / undefined on a prop seems sorta useless (it'd default to that anyway).

Actual behavior:
Error: Property 'a' is missing in type '{ c: 1; }'

How much of this is by design?

Related comment by @niieani:

I think the TypeScript team mentioned somewhere that | undefined should be considered equivalent to ? -- i.e. it aligns with their goals. For most intents and purposes this is how TS currently behaves, although I see what you mean by compiler differentiating somehow.
For example Flow treats these (? and | void) as different things, i.e. you could technically have a property and expect its type to be undefined. However for (all?) practical reasons they are pretty much the same.

I used to suggest that use never for optional parameter, but it seems never is not the right type, see #14452 (comment).

Thus I realize that ? is currently the only way to set a parameter to be optional, for example:

type A = {
    a: undefined;
    b: string;
}
type X = A['a']; //=> undefined
const a: A = {b: 'str'};
//    ^ [ts]
// Type '{ b: string; }' is not assignable to type '{ a: undefined; b: string; }'.
//   Property 'a' is missing in type '{ b: string; }'.

type B = {
    a: never;
    b: string;
}
type Y = B['a']; //=> never
const b: B = {b: 'str'};
//    ^ [ts]
// Type '{ b: string; }' is not assignable to type 'B'.
//   Property 'a' is missing in type '{ b: string; }'.

type C = {
    a?: undefined;
    b: string;
}
type Z = C['a']; //=> undefined
const c: C = {b: 'str'};
// passed

Thanks for your response. Pinging @dleavitt too. Dupe of #13195 then?