mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-10 10:58:20 -05:00
Merge pull request #28948 from Microsoft/discriminatedUnionIndexSignature
Fix crash related to discriminated unions with index signatures
This commit is contained in:
@@ -4715,6 +4715,10 @@ namespace ts {
|
||||
return prop ? getTypeOfSymbol(prop) : undefined;
|
||||
}
|
||||
|
||||
function getTypeOfPropertyOrIndexSignature(type: Type, name: __String): Type {
|
||||
return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, IndexKind.Number) || getIndexTypeOfType(type, IndexKind.String) || unknownType;
|
||||
}
|
||||
|
||||
function isTypeAny(type: Type | undefined) {
|
||||
return type && (type.flags & TypeFlags.Any) !== 0;
|
||||
}
|
||||
@@ -15657,7 +15661,7 @@ namespace ts {
|
||||
}
|
||||
const propType = getTypeOfPropertyOfType(type, propName);
|
||||
const narrowedPropType = propType && narrowType(propType);
|
||||
return propType === narrowedPropType ? type : filterType(type, t => isTypeComparableTo(getTypeOfPropertyOfType(t, propName)!, narrowedPropType!));
|
||||
return propType === narrowedPropType ? type : filterType(type, t => isTypeComparableTo(getTypeOfPropertyOrIndexSignature(t, propName), narrowedPropType!));
|
||||
}
|
||||
|
||||
function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type {
|
||||
|
||||
@@ -83,4 +83,26 @@ tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(32,11): error TS
|
||||
const data: null = carrier.data
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #28935
|
||||
|
||||
type Foo = { tag: true, x: number } | { tag: false, y: number } | { [x: string]: string };
|
||||
|
||||
function f30(foo: Foo) {
|
||||
if (foo.tag) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f31(foo: Foo) {
|
||||
if (foo.tag === true) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,28 @@ function f20<Data>(carrier: DataCarrier<Data>) {
|
||||
const data: null = carrier.data
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #28935
|
||||
|
||||
type Foo = { tag: true, x: number } | { tag: false, y: number } | { [x: string]: string };
|
||||
|
||||
function f30(foo: Foo) {
|
||||
if (foo.tag) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f31(foo: Foo) {
|
||||
if (foo.tag === true) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [discriminatedUnionTypes2.js]
|
||||
@@ -126,3 +148,19 @@ function f20(carrier) {
|
||||
var data = carrier.data;
|
||||
}
|
||||
}
|
||||
function f30(foo) {
|
||||
if (foo.tag) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
function f31(foo) {
|
||||
if (foo.tag === true) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,3 +225,51 @@ function f20<Data>(carrier: DataCarrier<Data>) {
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #28935
|
||||
|
||||
type Foo = { tag: true, x: number } | { tag: false, y: number } | { [x: string]: string };
|
||||
>Foo : Symbol(Foo, Decl(discriminatedUnionTypes2.ts, 71, 1))
|
||||
>tag : Symbol(tag, Decl(discriminatedUnionTypes2.ts, 75, 12))
|
||||
>x : Symbol(x, Decl(discriminatedUnionTypes2.ts, 75, 23))
|
||||
>tag : Symbol(tag, Decl(discriminatedUnionTypes2.ts, 75, 39))
|
||||
>y : Symbol(y, Decl(discriminatedUnionTypes2.ts, 75, 51))
|
||||
>x : Symbol(x, Decl(discriminatedUnionTypes2.ts, 75, 69))
|
||||
|
||||
function f30(foo: Foo) {
|
||||
>f30 : Symbol(f30, Decl(discriminatedUnionTypes2.ts, 75, 90))
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 77, 13))
|
||||
>Foo : Symbol(Foo, Decl(discriminatedUnionTypes2.ts, 71, 1))
|
||||
|
||||
if (foo.tag) {
|
||||
>foo.tag : Symbol(tag, Decl(discriminatedUnionTypes2.ts, 75, 12), Decl(discriminatedUnionTypes2.ts, 75, 39))
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 77, 13))
|
||||
>tag : Symbol(tag, Decl(discriminatedUnionTypes2.ts, 75, 12), Decl(discriminatedUnionTypes2.ts, 75, 39))
|
||||
|
||||
foo;
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 77, 13))
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 77, 13))
|
||||
}
|
||||
}
|
||||
|
||||
function f31(foo: Foo) {
|
||||
>f31 : Symbol(f31, Decl(discriminatedUnionTypes2.ts, 84, 1))
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 86, 13))
|
||||
>Foo : Symbol(Foo, Decl(discriminatedUnionTypes2.ts, 71, 1))
|
||||
|
||||
if (foo.tag === true) {
|
||||
>foo.tag : Symbol(tag, Decl(discriminatedUnionTypes2.ts, 75, 12), Decl(discriminatedUnionTypes2.ts, 75, 39))
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 86, 13))
|
||||
>tag : Symbol(tag, Decl(discriminatedUnionTypes2.ts, 75, 12), Decl(discriminatedUnionTypes2.ts, 75, 39))
|
||||
|
||||
foo;
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 86, 13))
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
>foo : Symbol(foo, Decl(discriminatedUnionTypes2.ts, 86, 13))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -239,3 +239,53 @@ function f20<Data>(carrier: DataCarrier<Data>) {
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #28935
|
||||
|
||||
type Foo = { tag: true, x: number } | { tag: false, y: number } | { [x: string]: string };
|
||||
>Foo : Foo
|
||||
>tag : true
|
||||
>true : true
|
||||
>x : number
|
||||
>tag : false
|
||||
>false : false
|
||||
>y : number
|
||||
>x : string
|
||||
|
||||
function f30(foo: Foo) {
|
||||
>f30 : (foo: Foo) => void
|
||||
>foo : Foo
|
||||
|
||||
if (foo.tag) {
|
||||
>foo.tag : string | boolean
|
||||
>foo : Foo
|
||||
>tag : string | boolean
|
||||
|
||||
foo;
|
||||
>foo : { tag: true; x: number; } | { [x: string]: string; }
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
>foo : { tag: false; y: number; } | { [x: string]: string; }
|
||||
}
|
||||
}
|
||||
|
||||
function f31(foo: Foo) {
|
||||
>f31 : (foo: Foo) => void
|
||||
>foo : Foo
|
||||
|
||||
if (foo.tag === true) {
|
||||
>foo.tag === true : boolean
|
||||
>foo.tag : string | boolean
|
||||
>foo : Foo
|
||||
>tag : string | boolean
|
||||
>true : true
|
||||
|
||||
foo;
|
||||
>foo : { tag: true; x: number; }
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
>foo : { tag: false; y: number; } | { [x: string]: string; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,3 +72,25 @@ function f20<Data>(carrier: DataCarrier<Data>) {
|
||||
const data: null = carrier.data
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #28935
|
||||
|
||||
type Foo = { tag: true, x: number } | { tag: false, y: number } | { [x: string]: string };
|
||||
|
||||
function f30(foo: Foo) {
|
||||
if (foo.tag) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f31(foo: Foo) {
|
||||
if (foo.tag === true) {
|
||||
foo;
|
||||
}
|
||||
else {
|
||||
foo;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user