diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 87f3b5a70b61e..c332d41a601bb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14246,8 +14246,10 @@ namespace ts { // a symbol-like type and a type known to be non-symbol-like, or // a void-like type and a type known to be non-void-like, or // a non-primitive type and a type known to be primitive. - if (includes & TypeFlags.Never || - strictNullChecks && includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || + if (includes & TypeFlags.Never) { + return contains(typeSet, silentNeverType) ? silentNeverType : neverType; + } + if (strictNullChecks && includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || includes & TypeFlags.NonPrimitive && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) || includes & TypeFlags.StringLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) || includes & TypeFlags.NumberLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) || diff --git a/tests/baselines/reference/silentNeverPropagation.js b/tests/baselines/reference/silentNeverPropagation.js new file mode 100644 index 0000000000000..cb6548632027f --- /dev/null +++ b/tests/baselines/reference/silentNeverPropagation.js @@ -0,0 +1,56 @@ +//// [silentNeverPropagation.ts] +// Repro from #45041 + +type ModuleWithState = { + state: TState; +}; + +type State = { + a: number; +}; + +type MoreState = { + z: string; +}; + +declare function createModule(state: TState, actions: TActions): ModuleWithState & TActions; + +declare function convert(m: ModuleWithState & TActions): ModuleWithState & TActions; + +const breaks = convert( + createModule({ a: 12 }, { foo() { return true } }) +); + +breaks.state.a +breaks.state.z +breaks.foo() + + +//// [silentNeverPropagation.js] +"use strict"; +// Repro from #45041 +var breaks = convert(createModule({ a: 12 }, { foo: function () { return true; } })); +breaks.state.a; +breaks.state.z; +breaks.foo(); + + +//// [silentNeverPropagation.d.ts] +declare type ModuleWithState = { + state: TState; +}; +declare type State = { + a: number; +}; +declare type MoreState = { + z: string; +}; +declare function createModule(state: TState, actions: TActions): ModuleWithState & TActions; +declare function convert(m: ModuleWithState & TActions): ModuleWithState & TActions; +declare const breaks: ModuleWithState<{ + a: number; +} & MoreState> & ModuleWithState<{ + a: number; +}> & { + foo(): true; +}; diff --git a/tests/baselines/reference/silentNeverPropagation.symbols b/tests/baselines/reference/silentNeverPropagation.symbols new file mode 100644 index 0000000000000..d52a2436fa4d4 --- /dev/null +++ b/tests/baselines/reference/silentNeverPropagation.symbols @@ -0,0 +1,84 @@ +=== tests/cases/compiler/silentNeverPropagation.ts === +// Repro from #45041 + +type ModuleWithState = { +>ModuleWithState : Symbol(ModuleWithState, Decl(silentNeverPropagation.ts, 0, 0)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 2, 21)) + + state: TState; +>state : Symbol(state, Decl(silentNeverPropagation.ts, 2, 32)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 2, 21)) + +}; + +type State = { +>State : Symbol(State, Decl(silentNeverPropagation.ts, 4, 2)) + + a: number; +>a : Symbol(a, Decl(silentNeverPropagation.ts, 6, 14)) + +}; + +type MoreState = { +>MoreState : Symbol(MoreState, Decl(silentNeverPropagation.ts, 8, 2)) + + z: string; +>z : Symbol(z, Decl(silentNeverPropagation.ts, 10, 18)) + +}; + +declare function createModule(state: TState, actions: TActions): ModuleWithState & TActions; +>createModule : Symbol(createModule, Decl(silentNeverPropagation.ts, 12, 2)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 14, 30)) +>TActions : Symbol(TActions, Decl(silentNeverPropagation.ts, 14, 37)) +>state : Symbol(state, Decl(silentNeverPropagation.ts, 14, 48)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 14, 30)) +>actions : Symbol(actions, Decl(silentNeverPropagation.ts, 14, 62)) +>TActions : Symbol(TActions, Decl(silentNeverPropagation.ts, 14, 37)) +>ModuleWithState : Symbol(ModuleWithState, Decl(silentNeverPropagation.ts, 0, 0)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 14, 30)) +>TActions : Symbol(TActions, Decl(silentNeverPropagation.ts, 14, 37)) + +declare function convert(m: ModuleWithState & TActions): ModuleWithState & TActions; +>convert : Symbol(convert, Decl(silentNeverPropagation.ts, 14, 118)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 16, 25)) +>TActions : Symbol(TActions, Decl(silentNeverPropagation.ts, 16, 32)) +>m : Symbol(m, Decl(silentNeverPropagation.ts, 16, 43)) +>ModuleWithState : Symbol(ModuleWithState, Decl(silentNeverPropagation.ts, 0, 0)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 16, 25)) +>TActions : Symbol(TActions, Decl(silentNeverPropagation.ts, 16, 32)) +>ModuleWithState : Symbol(ModuleWithState, Decl(silentNeverPropagation.ts, 0, 0)) +>TState : Symbol(TState, Decl(silentNeverPropagation.ts, 16, 25)) +>MoreState : Symbol(MoreState, Decl(silentNeverPropagation.ts, 8, 2)) +>TActions : Symbol(TActions, Decl(silentNeverPropagation.ts, 16, 32)) + +const breaks = convert( +>breaks : Symbol(breaks, Decl(silentNeverPropagation.ts, 18, 5)) +>convert : Symbol(convert, Decl(silentNeverPropagation.ts, 14, 118)) + + createModule({ a: 12 }, { foo() { return true } }) +>createModule : Symbol(createModule, Decl(silentNeverPropagation.ts, 12, 2)) +>a : Symbol(a, Decl(silentNeverPropagation.ts, 19, 18)) +>foo : Symbol(foo, Decl(silentNeverPropagation.ts, 19, 29)) + +); + +breaks.state.a +>breaks.state.a : Symbol(a, Decl(silentNeverPropagation.ts, 19, 18)) +>breaks.state : Symbol(state, Decl(silentNeverPropagation.ts, 2, 32), Decl(silentNeverPropagation.ts, 2, 32)) +>breaks : Symbol(breaks, Decl(silentNeverPropagation.ts, 18, 5)) +>state : Symbol(state, Decl(silentNeverPropagation.ts, 2, 32), Decl(silentNeverPropagation.ts, 2, 32)) +>a : Symbol(a, Decl(silentNeverPropagation.ts, 19, 18)) + +breaks.state.z +>breaks.state.z : Symbol(z, Decl(silentNeverPropagation.ts, 10, 18)) +>breaks.state : Symbol(state, Decl(silentNeverPropagation.ts, 2, 32), Decl(silentNeverPropagation.ts, 2, 32)) +>breaks : Symbol(breaks, Decl(silentNeverPropagation.ts, 18, 5)) +>state : Symbol(state, Decl(silentNeverPropagation.ts, 2, 32), Decl(silentNeverPropagation.ts, 2, 32)) +>z : Symbol(z, Decl(silentNeverPropagation.ts, 10, 18)) + +breaks.foo() +>breaks.foo : Symbol(foo, Decl(silentNeverPropagation.ts, 19, 29)) +>breaks : Symbol(breaks, Decl(silentNeverPropagation.ts, 18, 5)) +>foo : Symbol(foo, Decl(silentNeverPropagation.ts, 19, 29)) + diff --git a/tests/baselines/reference/silentNeverPropagation.types b/tests/baselines/reference/silentNeverPropagation.types new file mode 100644 index 0000000000000..c64dfc61f6e96 --- /dev/null +++ b/tests/baselines/reference/silentNeverPropagation.types @@ -0,0 +1,73 @@ +=== tests/cases/compiler/silentNeverPropagation.ts === +// Repro from #45041 + +type ModuleWithState = { +>ModuleWithState : ModuleWithState + + state: TState; +>state : TState + +}; + +type State = { +>State : State + + a: number; +>a : number + +}; + +type MoreState = { +>MoreState : MoreState + + z: string; +>z : string + +}; + +declare function createModule(state: TState, actions: TActions): ModuleWithState & TActions; +>createModule : (state: TState, actions: TActions) => ModuleWithState & TActions +>state : TState +>actions : TActions + +declare function convert(m: ModuleWithState & TActions): ModuleWithState & TActions; +>convert : (m: ModuleWithState & TActions) => ModuleWithState & TActions +>m : ModuleWithState & TActions + +const breaks = convert( +>breaks : ModuleWithState<{ a: number; } & MoreState> & ModuleWithState<{ a: number; }> & { foo(): true; } +>convert( createModule({ a: 12 }, { foo() { return true } })) : ModuleWithState<{ a: number; } & MoreState> & ModuleWithState<{ a: number; }> & { foo(): true; } +>convert : (m: ModuleWithState & TActions) => ModuleWithState & TActions + + createModule({ a: 12 }, { foo() { return true } }) +>createModule({ a: 12 }, { foo() { return true } }) : ModuleWithState<{ a: number; }> & { foo(): true; } +>createModule : (state: TState, actions: TActions) => ModuleWithState & TActions +>{ a: 12 } : { a: number; } +>a : number +>12 : 12 +>{ foo() { return true } } : { foo(): true; } +>foo : () => true +>true : true + +); + +breaks.state.a +>breaks.state.a : number +>breaks.state : { a: number; } & MoreState +>breaks : ModuleWithState<{ a: number; } & MoreState> & ModuleWithState<{ a: number; }> & { foo(): true; } +>state : { a: number; } & MoreState +>a : number + +breaks.state.z +>breaks.state.z : string +>breaks.state : { a: number; } & MoreState +>breaks : ModuleWithState<{ a: number; } & MoreState> & ModuleWithState<{ a: number; }> & { foo(): true; } +>state : { a: number; } & MoreState +>z : string + +breaks.foo() +>breaks.foo() : true +>breaks.foo : () => true +>breaks : ModuleWithState<{ a: number; } & MoreState> & ModuleWithState<{ a: number; }> & { foo(): true; } +>foo : () => true + diff --git a/tests/cases/compiler/silentNeverPropagation.ts b/tests/cases/compiler/silentNeverPropagation.ts new file mode 100644 index 0000000000000..4fb46c0c9bbd1 --- /dev/null +++ b/tests/cases/compiler/silentNeverPropagation.ts @@ -0,0 +1,28 @@ +// @strict: true +// @declaration: true + +// Repro from #45041 + +type ModuleWithState = { + state: TState; +}; + +type State = { + a: number; +}; + +type MoreState = { + z: string; +}; + +declare function createModule(state: TState, actions: TActions): ModuleWithState & TActions; + +declare function convert(m: ModuleWithState & TActions): ModuleWithState & TActions; + +const breaks = convert( + createModule({ a: 12 }, { foo() { return true } }) +); + +breaks.state.a +breaks.state.z +breaks.foo()