mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-20 05:17:43 -05:00
Port microsoft/typescript-go#1757 (#62501)
This commit is contained in:
@@ -27885,24 +27885,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
for (const type of types) {
|
||||
if (type.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.InstantiableNonPrimitive)) {
|
||||
const discriminant = getTypeOfPropertyOfType(type, name);
|
||||
if (discriminant) {
|
||||
if (!isLiteralType(discriminant)) {
|
||||
return undefined;
|
||||
}
|
||||
let duplicate = false;
|
||||
forEachType(discriminant, t => {
|
||||
const id = getTypeId(getRegularTypeOfLiteralType(t));
|
||||
const existing = map.get(id);
|
||||
if (!existing) {
|
||||
map.set(id, type);
|
||||
}
|
||||
else if (existing !== unknownType) {
|
||||
map.set(id, unknownType);
|
||||
duplicate = true;
|
||||
}
|
||||
});
|
||||
if (!duplicate) count++;
|
||||
if (!discriminant || !isLiteralType(discriminant)) {
|
||||
return undefined;
|
||||
}
|
||||
let duplicate = false;
|
||||
forEachType(discriminant, t => {
|
||||
const id = getTypeId(getRegularTypeOfLiteralType(t));
|
||||
const existing = map.get(id);
|
||||
if (!existing) {
|
||||
map.set(id, type);
|
||||
}
|
||||
else if (existing !== unknownType) {
|
||||
map.set(id, unknownType);
|
||||
duplicate = true;
|
||||
}
|
||||
});
|
||||
if (!duplicate) count++;
|
||||
}
|
||||
}
|
||||
return count >= 10 && count * 2 >= types.length ? map : undefined;
|
||||
|
||||
41
tests/baselines/reference/missingDiscriminants2.errors.txt
Normal file
41
tests/baselines/reference/missingDiscriminants2.errors.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
missingDiscriminants2.ts(30,23): error TS2353: Object literal may only specify known properties, and 'subkind' does not exist in type '{ kind: "b"; }'.
|
||||
missingDiscriminants2.ts(31,34): error TS2353: Object literal may only specify known properties, and 'subkind' does not exist in type '{ kind: "b"; }'.
|
||||
|
||||
|
||||
==== missingDiscriminants2.ts (2 errors) ====
|
||||
// https://github.com/microsoft/typescript-go/issues/1020
|
||||
|
||||
type Thing =
|
||||
| { str: "a", num: 0 }
|
||||
| { str: "b" }
|
||||
| { str: "c" }
|
||||
| { str: "d" }
|
||||
| { str: "e" }
|
||||
| { str: "f" }
|
||||
| { str: "g" }
|
||||
| { str: "h" }
|
||||
| { str: "i" }
|
||||
| { str: "j" }
|
||||
| { str: "k" }
|
||||
| { str: "l" }
|
||||
| { str: "m" }
|
||||
| { str: "n" }
|
||||
| { str: "o" }
|
||||
| { num: 1 }
|
||||
|
||||
const thing1: Thing = { str: "a", num: 0 }
|
||||
const thing2: Thing = { str: "b", num: 1 } // Shouldn't be error
|
||||
const thing3: Thing = { num: 1, str: "b" } // Shouldn't be error
|
||||
|
||||
type Item =
|
||||
| { kind: "a", subkind: 0, value: string }
|
||||
| { kind: "a", subkind: 1, value: number }
|
||||
| { kind: "b" }
|
||||
|
||||
const item1: Item = { subkind: 1, kind: "b" } // Error, type "b" not assignable to type "a"
|
||||
~~~~~~~
|
||||
!!! error TS2353: Object literal may only specify known properties, and 'subkind' does not exist in type '{ kind: "b"; }'.
|
||||
const item2: Item = { kind: "b", subkind: 1 } // Error, 'subkind' isn't a known property
|
||||
~~~~~~~
|
||||
!!! error TS2353: Object literal may only specify known properties, and 'subkind' does not exist in type '{ kind: "b"; }'.
|
||||
|
||||
103
tests/baselines/reference/missingDiscriminants2.symbols
Normal file
103
tests/baselines/reference/missingDiscriminants2.symbols
Normal file
@@ -0,0 +1,103 @@
|
||||
//// [tests/cases/compiler/missingDiscriminants2.ts] ////
|
||||
|
||||
=== missingDiscriminants2.ts ===
|
||||
// https://github.com/microsoft/typescript-go/issues/1020
|
||||
|
||||
type Thing =
|
||||
>Thing : Symbol(Thing, Decl(missingDiscriminants2.ts, 0, 0))
|
||||
|
||||
| { str: "a", num: 0 }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 3, 5))
|
||||
>num : Symbol(num, Decl(missingDiscriminants2.ts, 3, 15))
|
||||
|
||||
| { str: "b" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 4, 5))
|
||||
|
||||
| { str: "c" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 5, 5))
|
||||
|
||||
| { str: "d" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 6, 5))
|
||||
|
||||
| { str: "e" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 7, 5))
|
||||
|
||||
| { str: "f" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 8, 5))
|
||||
|
||||
| { str: "g" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 9, 5))
|
||||
|
||||
| { str: "h" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 10, 5))
|
||||
|
||||
| { str: "i" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 11, 5))
|
||||
|
||||
| { str: "j" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 12, 5))
|
||||
|
||||
| { str: "k" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 13, 5))
|
||||
|
||||
| { str: "l" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 14, 5))
|
||||
|
||||
| { str: "m" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 15, 5))
|
||||
|
||||
| { str: "n" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 16, 5))
|
||||
|
||||
| { str: "o" }
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 17, 5))
|
||||
|
||||
| { num: 1 }
|
||||
>num : Symbol(num, Decl(missingDiscriminants2.ts, 18, 5))
|
||||
|
||||
const thing1: Thing = { str: "a", num: 0 }
|
||||
>thing1 : Symbol(thing1, Decl(missingDiscriminants2.ts, 20, 5))
|
||||
>Thing : Symbol(Thing, Decl(missingDiscriminants2.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 20, 23))
|
||||
>num : Symbol(num, Decl(missingDiscriminants2.ts, 20, 33))
|
||||
|
||||
const thing2: Thing = { str: "b", num: 1 } // Shouldn't be error
|
||||
>thing2 : Symbol(thing2, Decl(missingDiscriminants2.ts, 21, 5))
|
||||
>Thing : Symbol(Thing, Decl(missingDiscriminants2.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 21, 23))
|
||||
>num : Symbol(num, Decl(missingDiscriminants2.ts, 21, 33))
|
||||
|
||||
const thing3: Thing = { num: 1, str: "b" } // Shouldn't be error
|
||||
>thing3 : Symbol(thing3, Decl(missingDiscriminants2.ts, 22, 5))
|
||||
>Thing : Symbol(Thing, Decl(missingDiscriminants2.ts, 0, 0))
|
||||
>num : Symbol(num, Decl(missingDiscriminants2.ts, 22, 23))
|
||||
>str : Symbol(str, Decl(missingDiscriminants2.ts, 22, 31))
|
||||
|
||||
type Item =
|
||||
>Item : Symbol(Item, Decl(missingDiscriminants2.ts, 22, 42))
|
||||
|
||||
| { kind: "a", subkind: 0, value: string }
|
||||
>kind : Symbol(kind, Decl(missingDiscriminants2.ts, 25, 5))
|
||||
>subkind : Symbol(subkind, Decl(missingDiscriminants2.ts, 25, 16))
|
||||
>value : Symbol(value, Decl(missingDiscriminants2.ts, 25, 28))
|
||||
|
||||
| { kind: "a", subkind: 1, value: number }
|
||||
>kind : Symbol(kind, Decl(missingDiscriminants2.ts, 26, 5))
|
||||
>subkind : Symbol(subkind, Decl(missingDiscriminants2.ts, 26, 16))
|
||||
>value : Symbol(value, Decl(missingDiscriminants2.ts, 26, 28))
|
||||
|
||||
| { kind: "b" }
|
||||
>kind : Symbol(kind, Decl(missingDiscriminants2.ts, 27, 5))
|
||||
|
||||
const item1: Item = { subkind: 1, kind: "b" } // Error, type "b" not assignable to type "a"
|
||||
>item1 : Symbol(item1, Decl(missingDiscriminants2.ts, 29, 5))
|
||||
>Item : Symbol(Item, Decl(missingDiscriminants2.ts, 22, 42))
|
||||
>subkind : Symbol(subkind, Decl(missingDiscriminants2.ts, 29, 21))
|
||||
>kind : Symbol(kind, Decl(missingDiscriminants2.ts, 29, 33))
|
||||
|
||||
const item2: Item = { kind: "b", subkind: 1 } // Error, 'subkind' isn't a known property
|
||||
>item2 : Symbol(item2, Decl(missingDiscriminants2.ts, 30, 5))
|
||||
>Item : Symbol(Item, Decl(missingDiscriminants2.ts, 22, 42))
|
||||
>kind : Symbol(kind, Decl(missingDiscriminants2.ts, 30, 21))
|
||||
>subkind : Symbol(subkind, Decl(missingDiscriminants2.ts, 30, 32))
|
||||
|
||||
169
tests/baselines/reference/missingDiscriminants2.types
Normal file
169
tests/baselines/reference/missingDiscriminants2.types
Normal file
@@ -0,0 +1,169 @@
|
||||
//// [tests/cases/compiler/missingDiscriminants2.ts] ////
|
||||
|
||||
=== missingDiscriminants2.ts ===
|
||||
// https://github.com/microsoft/typescript-go/issues/1020
|
||||
|
||||
type Thing =
|
||||
>Thing : Thing
|
||||
> : ^^^^^
|
||||
|
||||
| { str: "a", num: 0 }
|
||||
>str : "a"
|
||||
> : ^^^
|
||||
>num : 0
|
||||
> : ^
|
||||
|
||||
| { str: "b" }
|
||||
>str : "b"
|
||||
> : ^^^
|
||||
|
||||
| { str: "c" }
|
||||
>str : "c"
|
||||
> : ^^^
|
||||
|
||||
| { str: "d" }
|
||||
>str : "d"
|
||||
> : ^^^
|
||||
|
||||
| { str: "e" }
|
||||
>str : "e"
|
||||
> : ^^^
|
||||
|
||||
| { str: "f" }
|
||||
>str : "f"
|
||||
> : ^^^
|
||||
|
||||
| { str: "g" }
|
||||
>str : "g"
|
||||
> : ^^^
|
||||
|
||||
| { str: "h" }
|
||||
>str : "h"
|
||||
> : ^^^
|
||||
|
||||
| { str: "i" }
|
||||
>str : "i"
|
||||
> : ^^^
|
||||
|
||||
| { str: "j" }
|
||||
>str : "j"
|
||||
> : ^^^
|
||||
|
||||
| { str: "k" }
|
||||
>str : "k"
|
||||
> : ^^^
|
||||
|
||||
| { str: "l" }
|
||||
>str : "l"
|
||||
> : ^^^
|
||||
|
||||
| { str: "m" }
|
||||
>str : "m"
|
||||
> : ^^^
|
||||
|
||||
| { str: "n" }
|
||||
>str : "n"
|
||||
> : ^^^
|
||||
|
||||
| { str: "o" }
|
||||
>str : "o"
|
||||
> : ^^^
|
||||
|
||||
| { num: 1 }
|
||||
>num : 1
|
||||
> : ^
|
||||
|
||||
const thing1: Thing = { str: "a", num: 0 }
|
||||
>thing1 : Thing
|
||||
> : ^^^^^
|
||||
>{ str: "a", num: 0 } : { str: "a"; num: 0; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^
|
||||
>str : "a"
|
||||
> : ^^^
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
>num : 0
|
||||
> : ^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
const thing2: Thing = { str: "b", num: 1 } // Shouldn't be error
|
||||
>thing2 : Thing
|
||||
> : ^^^^^
|
||||
>{ str: "b", num: 1 } : { str: "b"; num: 1; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^
|
||||
>str : "b"
|
||||
> : ^^^
|
||||
>"b" : "b"
|
||||
> : ^^^
|
||||
>num : 1
|
||||
> : ^
|
||||
>1 : 1
|
||||
> : ^
|
||||
|
||||
const thing3: Thing = { num: 1, str: "b" } // Shouldn't be error
|
||||
>thing3 : Thing
|
||||
> : ^^^^^
|
||||
>{ num: 1, str: "b" } : { num: 1; str: "b"; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^
|
||||
>num : 1
|
||||
> : ^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>str : "b"
|
||||
> : ^^^
|
||||
>"b" : "b"
|
||||
> : ^^^
|
||||
|
||||
type Item =
|
||||
>Item : Item
|
||||
> : ^^^^
|
||||
|
||||
| { kind: "a", subkind: 0, value: string }
|
||||
>kind : "a"
|
||||
> : ^^^
|
||||
>subkind : 0
|
||||
> : ^
|
||||
>value : string
|
||||
> : ^^^^^^
|
||||
|
||||
| { kind: "a", subkind: 1, value: number }
|
||||
>kind : "a"
|
||||
> : ^^^
|
||||
>subkind : 1
|
||||
> : ^
|
||||
>value : number
|
||||
> : ^^^^^^
|
||||
|
||||
| { kind: "b" }
|
||||
>kind : "b"
|
||||
> : ^^^
|
||||
|
||||
const item1: Item = { subkind: 1, kind: "b" } // Error, type "b" not assignable to type "a"
|
||||
>item1 : Item
|
||||
> : ^^^^
|
||||
>{ subkind: 1, kind: "b" } : { subkind: number; kind: "b"; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>subkind : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>kind : "b"
|
||||
> : ^^^
|
||||
>"b" : "b"
|
||||
> : ^^^
|
||||
|
||||
const item2: Item = { kind: "b", subkind: 1 } // Error, 'subkind' isn't a known property
|
||||
>item2 : Item
|
||||
> : ^^^^
|
||||
>{ kind: "b", subkind: 1 } : { kind: "b"; subkind: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>kind : "b"
|
||||
> : ^^^
|
||||
>"b" : "b"
|
||||
> : ^^^
|
||||
>subkind : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
|
||||
34
tests/cases/compiler/missingDiscriminants2.ts
Normal file
34
tests/cases/compiler/missingDiscriminants2.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/typescript-go/issues/1020
|
||||
|
||||
type Thing =
|
||||
| { str: "a", num: 0 }
|
||||
| { str: "b" }
|
||||
| { str: "c" }
|
||||
| { str: "d" }
|
||||
| { str: "e" }
|
||||
| { str: "f" }
|
||||
| { str: "g" }
|
||||
| { str: "h" }
|
||||
| { str: "i" }
|
||||
| { str: "j" }
|
||||
| { str: "k" }
|
||||
| { str: "l" }
|
||||
| { str: "m" }
|
||||
| { str: "n" }
|
||||
| { str: "o" }
|
||||
| { num: 1 }
|
||||
|
||||
const thing1: Thing = { str: "a", num: 0 }
|
||||
const thing2: Thing = { str: "b", num: 1 } // Shouldn't be error
|
||||
const thing3: Thing = { num: 1, str: "b" } // Shouldn't be error
|
||||
|
||||
type Item =
|
||||
| { kind: "a", subkind: 0, value: string }
|
||||
| { kind: "a", subkind: 1, value: number }
|
||||
| { kind: "b" }
|
||||
|
||||
const item1: Item = { subkind: 1, kind: "b" } // Error, type "b" not assignable to type "a"
|
||||
const item2: Item = { kind: "b", subkind: 1 } // Error, 'subkind' isn't a known property
|
||||
Reference in New Issue
Block a user