TypeScript/tests/cases/conformance/types/union/discriminatedUnionTypes2.ts
Anders Hejlsberg 71a91763f4
Fix33448 (#35513)
* Filter out discriminants of type 'never'.

* Add tests

* Accept new baselines

* Remove unnecessary '!' assertion
2019-12-12 06:45:46 -08:00

145 lines
2.7 KiB
TypeScript

// @strict: true
function f10(x : { kind: false, a: string } | { kind: true, b: string } | { kind: string, c: string }) {
if (x.kind === false) {
x.a;
}
else if (x.kind === true) {
x.b;
}
else {
x.c;
}
}
function f11(x : { kind: false, a: string } | { kind: true, b: string } | { kind: string, c: string }) {
switch (x.kind) {
case false:
x.a;
break;
case true:
x.b;
break;
default:
x.c;
}
}
function f13(x: { a: null; b: string } | { a: string, c: number }) {
x = { a: null, b: "foo", c: 4}; // Error
}
function f14<T>(x: { a: 0; b: string } | { a: T, c: number }) {
if (x.a === 0) {
x.b; // Error
}
}
type Result<T> = { error?: undefined, value: T } | { error: Error };
function f15(x: Result<number>) {
if (!x.error) {
x.value;
}
else {
x.error.message;
}
}
f15({ value: 10 });
f15({ error: new Error("boom") });
// Repro from #24193
interface WithError {
error: Error
data: null
}
interface WithoutError<Data> {
error: null
data: Data
}
type DataCarrier<Data> = WithError | WithoutError<Data>
function f20<Data>(carrier: DataCarrier<Data>) {
if (carrier.error === null) {
const error: null = carrier.error
const data: Data = carrier.data
} else {
const error: Error = carrier.error
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;
}
}
// Repro from #33448
type a = {
type: 'a',
data: string
}
type b = {
type: 'b',
name: string
}
type c = {
type: 'c',
other: string
}
type abc = a | b | c;
function f(problem: abc & (b | c)) {
if (problem.type === 'b') {
problem.name;
}
else {
problem.other;
}
}
type RuntimeValue =
| { type: 'number', value: number }
| { type: 'string', value: string }
| { type: 'boolean', value: boolean };
function foo1(x: RuntimeValue & { type: 'number' }) {
if (x.type === 'number') {
x.value; // number
}
else {
x.value; // Error, x is never
}
}
function foo2(x: RuntimeValue & ({ type: 'number' } | { type: 'string' })) {
if (x.type === 'number') {
x.value; // number
}
else {
x.value; // string
}
}