-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
assignabiltity between interfaces and types #14736
Comments
This is working as intended. See #7029 for the rationale. |
@ahejlsberg |
I believe the justification, reading #7029, is that a |
I see this. I've modified the code to narrow the issue down. I need to understand more about differences between Is there a strong recommendations where it is more appropriate to use |
extends
constrains with an interface
error
Back in my time we didn't have
|
@kitsonk Ok thanks for the explanation. |
Generally, given a type T with an index signature, a type S is assignable to T only if S has a compatible index signature. This rule ensures in a transitive manner that S is as least as constrained as T. Consider: interface Params {
[x: string]: string;
}
interface MyParams {
log: string;
}
const logWithNumber = {
log: "foo",
count: 42
};
let myParams: MyParams = logWithNumber; // Ok, source permitted to have additional properties
let params: Params = myParams; // Error Without the rule that requires a matching index signatures, the last line in the example above wouldn't be an error and we would have violated the index signature constraint of the target. Effectively, because of subtype substitutability, an instance of an interface type without an index signature may have additional properties that we know nothing about. However, when it comes to object literals, we do know that they don't have additional properties. Therefore, when the source is an object literal is it safe to permit assignment as long as all of the properties meet the constraint of the target. Now, the way we track that something is an object literal is by checking that its type originated in an object literal expression or an object literal type. The latter technically doesn't guarantee anything about additional properties (as you've discovered) but is included such that anything that applies to an inferred object literal type also applies to an explicitly specified object literal type. So it's a compromise we have to make for object literal types, but not for interface types. |
So I probably may close this one. Thanks for explanation. |
TypeScript Version: 2.2.1 / nightly (2.3.0)
I believe my issue can be narrowed down:
Actual behavior:
if to replace
interface
withtype
there is no error:The text was updated successfully, but these errors were encountered: