-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Index signature is assignable to weak type whose properties don't match the signature type #27144
Comments
I think of index signatures as asserting that a type may contain every property, in which case the weak type check is trivially satisfied. But if you think of them as having no defined properties, similar to |
Thanks for the prompt response!
That interpretation of an index signature doesn't seem consistent with the fact that TypeScript doesn't check that the return type of the index signature is compatible with the type of More practically, we've just heard from a user who mistakenly assigned a type with only an index signature to a weak type. Are there reasonable cases in which such an assignment is intentional? |
Ah, I didn't see the types. :) I have the weak type implementation so much in my head that I just looked at properties. So it sounds like the correct check for index signatures is to make sure that the signature type is assignable to the union of the weak type's property types. |
Well, here's what it looks like, inside the main weak type check: const index = getIndexInfoOfType(source, IndexKind.String);
if (index && !isRelatedTo(getIntersectionType([index.type, ...map(getPropertiesOfType(source), getTypeOfSymbol)]), getUnionType(map(getPropertiesOfType(target), getTypeOfSymbol)))) {
if (reportErrors) {
// NB Should have a specific error here
reportError(Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target));
}
return Ternary.False;
} This is a related check to the current weak type check, though. It's not the same thing. It says that even though there is a value that satisfies both types, that value is @DanielRosenwasser what do you think about this check? I need to run it on the user tests to see if it finds a bunch of errors, but nothing has turned up in suite 0 tests. Edit: Doesn't find any errors in the user test suite, although it's mostly Javascript, so not too many weak types there. Edit: Nope, nothing in RWC either. |
I didn't know a "Bug" could be "In Discussion". 😄 For that matter, if we interpret an index signature as "there might exist a property of any name", why do we ever allow a type with an index signature to be assignable to a type with an incompatible optional property, regardless of whether the target type is weak? Are there real-world cases in which the error would be undesirable? Example: interface Foo {
a: number;
b?: string;
}
interface Bar {
a: number
[n: string]: number;
}
let b: Bar = {a: 42, b: 43};
let f: Foo = b; // OK; expect error? |
@mattmccutchen I think you have found the real issue. I'm not sure why it works this why. Maybe the spec has a justification? |
against optional properties of the target. Fix one good break in the compiler itself. Fixes microsoft#27144.
I wanted to see how many TypeScript PRs I could submit in a day, so I went ahead and submitted #27591 to check a source index signature (or rest type if the source is a tuple type) against target optional properties. There was one good (IMO) break in the compiler itself. I guess you can see what happens with the "real-world code" suite. |
Relevant SO question where someone smacks into this. |
I think this issue could cause potential bugs in the code. If the PR was closed because existing code with potential issues fails to transpile, Would it be possible to consider implementing individual checks through options like StrictXXX? |
By the way, I had trouble with this Playground Link: link |
From https://stackoverflow.com/q/52368008 . Based on #16047 (comment), it appears that @sandersn may have thought about the rule, but it still makes no sense to me and no rationale is stated.
TypeScript Version: master (394ee31)
Search Terms: weak type index signature
Code
Expected behavior: Error: "Type 'Bar' has no properties in common with type 'Foo'."
Actual behavior: No error.
Playground Link: link
Related Issues: Possibly #9900
The text was updated successfully, but these errors were encountered: