-
Notifications
You must be signed in to change notification settings - Fork 12.8k
[regression 4.8] type narrowed too far; valid cases considered unreachable #50527
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
A shorter repo: // @strict: true
type S =
| { type: 'string', value: string }
| { type: 'number', value: number }
| { type: 'unknown', value: unknown }
| { value: undefined };
declare var s: S
if (s.value !== undefined) {
s;
//^?
// 4.7: var a: S;
// 4.8: var a: { type: 'unknown', value: unknown };
} 4.7 doesn't narrow the type at all, while 4.8 narrows it incorrectly. |
👋 Hi, I'm the Repro bot. I can help narrow down and track compiler bugs across releases! This comment reflects the current state of this repro running against the nightly TypeScript.
Historical Information
|
The change between 8002369 and v4.8.2 occurred at bdb8514. |
@typescript-bot bisect good 8002369 bad v4.8.2 |
The bot still gets hung up on 5aa0053... it looks like that's going to be an issue if the |
I think the test runner can work around it by treating its array of root files as immutable. I’ll do that sometime this week. #49736 is the alleged new culprit 😮 |
At a glance, that makes no sense whatsoever |
I'm not sure what the bot picked up on; when I do a bisect by hand, I get #49119 (which makes a lot of sense). @ahejlsberg |
I think I have a similar repro for this. // @strict: true
interface SuperType {
foo: number;
}
type First = Omit<SuperType, 'foo'> & {
a: string;
}
type Second = Omit<SuperType, 'foo'> & {
a: string;
foo: string;
}
function myFunction(props: First): void;
function myFunction(props: Second): void;
function myFunction(props: First|Second): void {
if (hasProperty(props, 'foo')) {
// ^?
// Props should be narrowed to Second at this point
// TS 4.8.2 claims props is Second | (Omit<SuperType, "foo"> & { a: string; } & Record<"foo", unknown>) | (Omit<SuperType, "foo"> & { a: string; foo: string; } & Record<...>)
// TS 4.8.0-beta claims props is Second
// TS 4.7.4 claims props is Second
const second: Second = props; // TSS 4.8.2 Error: Types of property 'foo' are incompatible. Type 'unknown' is not assignable to type 'string'.
console.log(second);
return;
}
// Props should be narrowed to First at this point
const first: First = props; // TS 4.8.2 claims this is First
console.log(first);
}
// This function is used for type-narrowing to determine if an arbitrary property exists on an object (and type it as such)
export function hasProperty<T, K extends string | number | symbol>(obj: T, prop: K): obj is T & Record<K, unknown> {
return obj !== undefined && obj !== null && Object.prototype.hasOwnProperty.call(obj, prop);
} Tracking issue status for this to drop in nightly |
@berickson1 I’m not sure exactly where that changed, but the new behavior is correct. |
Bug Report
🔎 Search Terms
type narrowing assertNever never unreachable
🕗 Version & Regression Information
⏯ Playground Link
Playground Link: Provided
💻 Code
Output
Compiler Options
🙁 Actual behavior
Code compiles without error, but
assertNever
is hit at runtime.🙂 Expected behavior
Compilation error: the type of
action.property
at the point it's passed toassertNever
is notnever
. (4.7 does this.)The text was updated successfully, but these errors were encountered: