-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Assertion signature on generics doesn't narrow #60130
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
Why is |
Why wouldn't it be? Does this violate any TS syntax? |
Because it's a generic type parameter that doesn't do anything. |
As most bug repros, it is a narrowed down snippet. I personally don't expect these to make programming sense. |
BTW If actually fixing it is for some reason infeasible, it is an entirely legit fix to document this as an assertion-signature limitation. But until either of these are taken - people will continue to be stung by such unexpected behavior. Please reconsider before ignoring this as 'not a defect'. |
Personally I'd expect any assertion signature to either narrow or produce an error as per #33622. Silently failing seems buggy. I'd be interested in seeing a more motivating use case, though. The behavior here is weird, though, it seems that it is narrowing (if you hover over |
I'd say the wish to not lose half a day over trying to silence ts complaints where there shouldn't have been any AND there are zero indications to any problem in some use of assertion-signature somewhere in your codebase, should suffice as motivation. |
Sure, great. But, I'm interested in where this actually shows up. I'm asking for something closer to the real use case. I get it, you don't think you should have to provide that. Maybe you're right. But I don't understand the pushback here. Anyway, I'll disengage. I hope to see this reclassified as a bug, if only for the silent failure. |
@jcalz sorry I didn't mean to come across as harsh. I really don't have a good use case, this is just how I found my codebase* and was expecting help from the compiler to handle it - either compiling it properly or complaining, but not silently perform an erroneous compilation. I don't think these are extravagant expectations and am quite confused as to the reaso s for marking this as a non-defect.
|
To add on to what @OfekShilon shared (we're both contributors to the Compiler Explorer project), I don't think we have a compelling motivating use case where it must be written with a generic. I had just written it like this and it worked fine everywhere except this one puzzling place. I'd be happy to link to our code where we're defining We can work around this by updating the assertion in our code to be If this is intended behavior or a design limitation of the generic version, +1 to:
|
Someone can send a PR if they figure out what's going on here.
I don't think anyone's ever tried to write this code before, because there's nothing you can do with a type parameter that is also meaningful in the context of an |
Probably the right behavior is to say that an |
The assertion signature here is a slight red herring, the same happens for any inferrable signature: declare function inferStuff<T>(arg: T, checkStuff?: boolean): T;
export function test(lines: string[]): string[] {
let func: {
name: string;
} | null = null;
for (const _ of lines) {
if (Math.random() < 0.5) {
func = {
name: "qwer",
};
} else {
if (func) {
const { name } = func; // errors here
func = inferStuff(
{
name: "other",
},
name === "abc",
);
}
}
}
return lines;
} But perhaps, here, it's easier to see that it can, indeed, create some circularity. The circularity itself happens when checking the argument's type when inferring into a signature. Its type has to be obtained as it's a potential source for that inference. In this particular case, it could be avoided because a binary expression with
One could have some generic asserts like: declare function assertSmth<T extends { kind: string }>(arg: T, c: boolean): asserts c; In this one, the |
π Search Terms
Assertion AND signature
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?noUncheckedIndexedAccess=true&allowUnusedLabels=true&downlevelIteration=true&noEmitHelpers=true&noUnusedLocals=true&noUnusedParameters=true&preserveConstEnums=true&removeComments=true&importHelpers=true&target=99&useUnknownInCatchVariables=false&exactOptionalPropertyTypes=true&noImplicitOverride=true&noFallthroughCasesInSwitch=true&noPropertyAccessFromIndexSignature=true&inlineSourceMap=true&inlineSources=true&stripInternal=true&ts=5.6.2#code/FAehAICIHEHtYCbgIYGdUFMBOAXSAucAW2QGsNVwEKcsBXAYxzqwEsA7Ac3FUYYwwJQEAGZ12TVrHYp02HAAoGhcaXawA7uwCUhNJlyUG4AN7DwFi6xHgFAQgbbT5y6-A4AFlk3h2GDeAAKgCeAA4YAKJY3lgKAOQAgnK4UjIiyKwANoJx2gDcLpYAvuYl5pAAQshI+vIEVDT0TCwc3NgxwGISOKmyBjgAPADCAHxKhEO6ffJGzq7Wtg5OZm6Wnt4BfgEh4VEx8Un9velZOfnAriVlGAAeobC44F2S0u40CpkcFISotK0A2gBdKa-NhcIHOC6rcDZHBPcTKObQ1zsZBEDA-P5cArI1yfPyoTFgzhAnHQorgAA+vjomUy4AAvDS6QUoasRA9bAxpL8YV9wLAbPiKMs2biFgoALLITwAOiwyHYCFgRAUTgG4AADLKAKyi3HQ56MpEG5Go9GESAARw02EgABoxaa3MLCeB-sLAY7nZcyQaKRhMpgTT7argFM9zj7LNz2LyTOaMPa+QSKUznnlLGBwAMGXnwBEAEqFgDyhfAAAkixEnabXbLQnRUB4Pl8o9HpuHE+A7Pm4sgAEYMXJ+3ElZHj6ESyO11ZYDDMLBpBGy12j1zzxcyNdiopAA
π» Code
π Actual behavior
When the generic-assert implementation is active, the line -
errors with
'name' implicitly has type 'any'
.When the
unknown
assert implementation is active, types are properly inferred.π Expected behavior
Both
assert
versions contain assertion signature, and both should be able to narrow the type.Additional information about the issue
No response
The text was updated successfully, but these errors were encountered: