-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Object literal strictness and unions #4452
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
Comments
That's a union type, not an intersection type. But technicalities aside, I understand why you might expect an error. We currently consider a property unknown if it doesn't exist in any of the constituent types in a union or intersection type on the target side. For example, if you specified a property |
@ahejlsberg good catch, updated If we have time, we can chat about this at the design meeting and update the bug after. |
Doesn't seem to be anyone hitting this badly in practice and the check we'd have to do to detect this error would be quite expensive. |
For posterity, I would like to record another instance of this same issue. With TypeScript 2.9.0-dev.20180402 the issue is still present. The following behavior confused me for a long time. It is a combination of this issue with a slightly confusing type Union = { name: string } | { age: number } | {};
type Base = {
// Try commenting out the base prop
base: boolean;
};
// Try replacing with just Union
function f(parameter: Base & Union) {}
// Notice the age field is invalid, but is not an error
f({ age: "John", base: true });
// Notice the non-existent field is an error
f({ nonExistent: "", base: true });
// Object literal may only specify known properties, and 'nonExistent' does not exist in type 'Base | (Base & { name: string; }) | (Base & { age: number; })'. (Try in the playground.) I don’t know which behavior would be most expected, but whatever treats Search optimization: empty interface, narrowing, intersection, union, set, known properties. |
Currently, if I have the following:
I get the error that "Argument of type '{ a: number; c: number; }' is not assignable to parameter of type '{ c: number; }'. Object literal may only specify known properties, and 'a' does not exist in type '{ c: number; }'."
Which makes sense, given our recent work on object literal strictness. What I'm not clear about is why this doesn't allow me to get an intuition about union types. For example, this does not error:
By inspection, I'd expect the above to give me an error. The object literal I'm passing in matches neither type in the union strictly, and it's arguable the parts it does seem to match are hinting that I'm doing something wrong.
As a user, wouldn't it be my expectation that I'm saying "strictly either an object with a of type string -or- an object of c with type number"?
The text was updated successfully, but these errors were encountered: