mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Normalize target type after null-stripping unions in relationship checks (#43202)
* Normalize target type after null-stripping * Add regression tests
This commit is contained in:
parent
451d4354b9
commit
fbc9c942b2
@ -17381,9 +17381,9 @@ namespace ts {
|
||||
(target as UnionType).types.length <= 3 && maybeTypeOfKind(target, TypeFlags.Nullable)) {
|
||||
const nullStrippedTarget = extractTypesOfKind(target, ~TypeFlags.Nullable);
|
||||
if (!(nullStrippedTarget.flags & (TypeFlags.Union | TypeFlags.Never))) {
|
||||
if (source === nullStrippedTarget) return Ternary.True;
|
||||
target = nullStrippedTarget;
|
||||
target = getNormalizedType(nullStrippedTarget, /*writing*/ true);
|
||||
}
|
||||
if (source === nullStrippedTarget) return Ternary.True;
|
||||
}
|
||||
|
||||
if (relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) ||
|
||||
|
||||
35
tests/baselines/reference/indexedAccessNormalization.js
Normal file
35
tests/baselines/reference/indexedAccessNormalization.js
Normal file
@ -0,0 +1,35 @@
|
||||
//// [indexedAccessNormalization.ts]
|
||||
// Repro from from #43152
|
||||
|
||||
type MyMap<M extends object> = {
|
||||
[K in keyof M]: {
|
||||
x: number
|
||||
}
|
||||
}
|
||||
|
||||
declare function g<T>(value?: T): void;
|
||||
|
||||
function f1<M extends object>(mymap: MyMap<M>, k: keyof M) {
|
||||
const elemofM = mymap[k];
|
||||
g(elemofM);
|
||||
}
|
||||
|
||||
function f2<M extends object>(mymap: MyMap<M>, k: keyof M, z: { x: number }) {
|
||||
const q1: MyMap<M>[keyof M] = z;
|
||||
const q2: MyMap<M>[keyof M] | undefined = z;
|
||||
const q3: MyMap<M>[keyof M] | string = z;
|
||||
}
|
||||
|
||||
|
||||
//// [indexedAccessNormalization.js]
|
||||
"use strict";
|
||||
// Repro from from #43152
|
||||
function f1(mymap, k) {
|
||||
var elemofM = mymap[k];
|
||||
g(elemofM);
|
||||
}
|
||||
function f2(mymap, k, z) {
|
||||
var q1 = z;
|
||||
var q2 = z;
|
||||
var q3 = z;
|
||||
}
|
||||
74
tests/baselines/reference/indexedAccessNormalization.symbols
Normal file
74
tests/baselines/reference/indexedAccessNormalization.symbols
Normal file
@ -0,0 +1,74 @@
|
||||
=== tests/cases/compiler/indexedAccessNormalization.ts ===
|
||||
// Repro from from #43152
|
||||
|
||||
type MyMap<M extends object> = {
|
||||
>MyMap : Symbol(MyMap, Decl(indexedAccessNormalization.ts, 0, 0))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 2, 11))
|
||||
|
||||
[K in keyof M]: {
|
||||
>K : Symbol(K, Decl(indexedAccessNormalization.ts, 3, 5))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 2, 11))
|
||||
|
||||
x: number
|
||||
>x : Symbol(x, Decl(indexedAccessNormalization.ts, 3, 21))
|
||||
}
|
||||
}
|
||||
|
||||
declare function g<T>(value?: T): void;
|
||||
>g : Symbol(g, Decl(indexedAccessNormalization.ts, 6, 1))
|
||||
>T : Symbol(T, Decl(indexedAccessNormalization.ts, 8, 19))
|
||||
>value : Symbol(value, Decl(indexedAccessNormalization.ts, 8, 22))
|
||||
>T : Symbol(T, Decl(indexedAccessNormalization.ts, 8, 19))
|
||||
|
||||
function f1<M extends object>(mymap: MyMap<M>, k: keyof M) {
|
||||
>f1 : Symbol(f1, Decl(indexedAccessNormalization.ts, 8, 39))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 10, 12))
|
||||
>mymap : Symbol(mymap, Decl(indexedAccessNormalization.ts, 10, 30))
|
||||
>MyMap : Symbol(MyMap, Decl(indexedAccessNormalization.ts, 0, 0))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 10, 12))
|
||||
>k : Symbol(k, Decl(indexedAccessNormalization.ts, 10, 46))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 10, 12))
|
||||
|
||||
const elemofM = mymap[k];
|
||||
>elemofM : Symbol(elemofM, Decl(indexedAccessNormalization.ts, 11, 9))
|
||||
>mymap : Symbol(mymap, Decl(indexedAccessNormalization.ts, 10, 30))
|
||||
>k : Symbol(k, Decl(indexedAccessNormalization.ts, 10, 46))
|
||||
|
||||
g(elemofM);
|
||||
>g : Symbol(g, Decl(indexedAccessNormalization.ts, 6, 1))
|
||||
>elemofM : Symbol(elemofM, Decl(indexedAccessNormalization.ts, 11, 9))
|
||||
}
|
||||
|
||||
function f2<M extends object>(mymap: MyMap<M>, k: keyof M, z: { x: number }) {
|
||||
>f2 : Symbol(f2, Decl(indexedAccessNormalization.ts, 13, 1))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>mymap : Symbol(mymap, Decl(indexedAccessNormalization.ts, 15, 30))
|
||||
>MyMap : Symbol(MyMap, Decl(indexedAccessNormalization.ts, 0, 0))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>k : Symbol(k, Decl(indexedAccessNormalization.ts, 15, 46))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>z : Symbol(z, Decl(indexedAccessNormalization.ts, 15, 58))
|
||||
>x : Symbol(x, Decl(indexedAccessNormalization.ts, 15, 63))
|
||||
|
||||
const q1: MyMap<M>[keyof M] = z;
|
||||
>q1 : Symbol(q1, Decl(indexedAccessNormalization.ts, 16, 9))
|
||||
>MyMap : Symbol(MyMap, Decl(indexedAccessNormalization.ts, 0, 0))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>z : Symbol(z, Decl(indexedAccessNormalization.ts, 15, 58))
|
||||
|
||||
const q2: MyMap<M>[keyof M] | undefined = z;
|
||||
>q2 : Symbol(q2, Decl(indexedAccessNormalization.ts, 17, 9))
|
||||
>MyMap : Symbol(MyMap, Decl(indexedAccessNormalization.ts, 0, 0))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>z : Symbol(z, Decl(indexedAccessNormalization.ts, 15, 58))
|
||||
|
||||
const q3: MyMap<M>[keyof M] | string = z;
|
||||
>q3 : Symbol(q3, Decl(indexedAccessNormalization.ts, 18, 9))
|
||||
>MyMap : Symbol(MyMap, Decl(indexedAccessNormalization.ts, 0, 0))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>M : Symbol(M, Decl(indexedAccessNormalization.ts, 15, 12))
|
||||
>z : Symbol(z, Decl(indexedAccessNormalization.ts, 15, 58))
|
||||
}
|
||||
|
||||
53
tests/baselines/reference/indexedAccessNormalization.types
Normal file
53
tests/baselines/reference/indexedAccessNormalization.types
Normal file
@ -0,0 +1,53 @@
|
||||
=== tests/cases/compiler/indexedAccessNormalization.ts ===
|
||||
// Repro from from #43152
|
||||
|
||||
type MyMap<M extends object> = {
|
||||
>MyMap : MyMap<M>
|
||||
|
||||
[K in keyof M]: {
|
||||
x: number
|
||||
>x : number
|
||||
}
|
||||
}
|
||||
|
||||
declare function g<T>(value?: T): void;
|
||||
>g : <T>(value?: T | undefined) => void
|
||||
>value : T | undefined
|
||||
|
||||
function f1<M extends object>(mymap: MyMap<M>, k: keyof M) {
|
||||
>f1 : <M extends object>(mymap: MyMap<M>, k: keyof M) => void
|
||||
>mymap : MyMap<M>
|
||||
>k : keyof M
|
||||
|
||||
const elemofM = mymap[k];
|
||||
>elemofM : MyMap<M>[keyof M]
|
||||
>mymap[k] : MyMap<M>[keyof M]
|
||||
>mymap : MyMap<M>
|
||||
>k : keyof M
|
||||
|
||||
g(elemofM);
|
||||
>g(elemofM) : void
|
||||
>g : <T>(value?: T | undefined) => void
|
||||
>elemofM : MyMap<M>[keyof M]
|
||||
}
|
||||
|
||||
function f2<M extends object>(mymap: MyMap<M>, k: keyof M, z: { x: number }) {
|
||||
>f2 : <M extends object>(mymap: MyMap<M>, k: keyof M, z: { x: number;}) => void
|
||||
>mymap : MyMap<M>
|
||||
>k : keyof M
|
||||
>z : { x: number; }
|
||||
>x : number
|
||||
|
||||
const q1: MyMap<M>[keyof M] = z;
|
||||
>q1 : MyMap<M>[keyof M]
|
||||
>z : { x: number; }
|
||||
|
||||
const q2: MyMap<M>[keyof M] | undefined = z;
|
||||
>q2 : MyMap<M>[keyof M] | undefined
|
||||
>z : { x: number; }
|
||||
|
||||
const q3: MyMap<M>[keyof M] | string = z;
|
||||
>q3 : string | MyMap<M>[keyof M]
|
||||
>z : { x: number; }
|
||||
}
|
||||
|
||||
22
tests/cases/compiler/indexedAccessNormalization.ts
Normal file
22
tests/cases/compiler/indexedAccessNormalization.ts
Normal file
@ -0,0 +1,22 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from from #43152
|
||||
|
||||
type MyMap<M extends object> = {
|
||||
[K in keyof M]: {
|
||||
x: number
|
||||
}
|
||||
}
|
||||
|
||||
declare function g<T>(value?: T): void;
|
||||
|
||||
function f1<M extends object>(mymap: MyMap<M>, k: keyof M) {
|
||||
const elemofM = mymap[k];
|
||||
g(elemofM);
|
||||
}
|
||||
|
||||
function f2<M extends object>(mymap: MyMap<M>, k: keyof M, z: { x: number }) {
|
||||
const q1: MyMap<M>[keyof M] = z;
|
||||
const q2: MyMap<M>[keyof M] | undefined = z;
|
||||
const q3: MyMap<M>[keyof M] | string = z;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user