TypeScript Version: Nightly
Search Terms: generic spread optional property
Code
interface Test {
readonly hi?: string[]
}
function test<T extends object>(value: T): Test {
return { ...value, hi: true }
}
Expected behavior:
This should fail to type check.
Actual behavior:
It passes. Interestingly, changing any of the following causes it to fail:
hi property non-optionalT with object.Related Issues: Not sure
While that's particularly egregious, the root cause is this:
interface Test {
readonly hi?: string[]
}
function test<T extends object>(value: T): Test {
return value; // `T` possibly doesn't satisfy `Test`
}
test({ hi: "potato" }); // ... clearly not a `Test`
T being assignable to Test seems.... dubious. Highly dubious.
Need 馃槻 reaction
T is assignable to {hi?: string[]} is apparently allowable because T is constrained to object, which is assignable to {hi?: string[]}.
const x: { hi?: string[] } = { hi: "no" } as object;
This, too, seems wrong.
And yet @ahejlsberg rates this as "Design Limitation", with "optional properties are very weakly checked; caveat empor"; so this is yours to triage now~
Optional properties were a mistake. /Half-kidding
As a rule of thumb, optional properties should only really be used in function/constructor parameter positions. And never as generic type constraints.
They shouldn't really be used in return types or other kinds of functions. Otherwise, you will find yourself in all kinds of soundness issues.
Not a TS team stance, just something I've personally observed.
Even when used to just type options objects for init, you can still run into soundness issues but they are far less likely to occur by accident
Moving fix back into 3.9.1 as I think it is very safe and has caught several legit issues.
Most helpful comment
Optional properties were a mistake. /Half-kidding
As a rule of thumb, optional properties should only really be used in function/constructor parameter positions. And never as generic type constraints.
They shouldn't really be used in return types or other kinds of functions. Otherwise, you will find yourself in all kinds of soundness issues.
Not a TS team stance, just something I've personally observed.
Even when used to just type options objects for init, you can still run into soundness issues but they are far less likely to occur by accident