1// see 'typeRelatedToDiscriminatedType' in checker.ts: 2 3// IteratorResult 4namespace Example1 { 5 type S = { done: boolean, value: number }; 6 type T = 7 | { done: true, value: number } // T0 8 | { done: false, value: number }; // T1 9 10 declare let s: S; 11 declare let t: T; 12 13 // S is assignable to T0 when S["done"] is true 14 // S is assignable to T1 when S["done"] is false 15 t = s; 16} 17 18// Dropping constituents of T 19namespace Example2 { 20 type S = { a: 0 | 2, b: 4 }; 21 type T = { a: 0, b: 1 | 4 } // T0 22 | { a: 1, b: 2 } // T1 23 | { a: 2, b: 3 | 4 }; // T2 24 declare let s: S; 25 declare let t: T; 26 27 // S is assignable to T0 when S["a"] is 0 28 // S is assignable to T2 when S["a"] is 2 29 t = s; 30} 31 32// Unmatched discriminants 33namespace Example3 { 34 type S = { a: 0 | 2, b: 4 }; 35 type T = { a: 0, b: 1 | 4 } // T0 36 | { a: 1, b: 2 | 4 } // T1 37 | { a: 2, b: 3 }; // T2 38 declare let s: S; 39 declare let t: T; 40 41 // S is assignable to T0 when S["a"] is 0 42 // S is *not* assignable to T1 when S["b"] is 4 43 // S is *not* assignable to T2 when S["a"] is 2 44 t = s; 45} 46 47// Unmatched non-discriminants 48namespace Example4 { 49 type S = { a: 0 | 2, b: 4 }; 50 type T = { a: 0, b: 1 | 4 } // T0 51 | { a: 1, b: 2 } // T1 52 | { a: 2, b: 3 | 4, c: string }; // T2 53 declare let s: S; 54 declare let t: T; 55 56 // S is assignable to T0 when S["a"] is 0 57 // S is *not* assignable to T2 when S["a"] is 2 as S is missing "c" 58 t = s; 59} 60 61// Maximum discriminant combinations 62namespace Example5 { 63 // NOTE: The maximum number of discriminant type combinations is currently 25. 64 // 3 discriminant properties with 3 types a piece 65 // is 27 possible combinations. 66 type N = 0 | 1 | 2; 67 type S = { a: N, b: N, c: N }; 68 type T = { a: 0, b: N, c: N } 69 | { a: 1, b: N, c: N } 70 | { a: 2, b: N, c: N } 71 | { a: N, b: 0, c: N } 72 | { a: N, b: 1, c: N } 73 | { a: N, b: 2, c: N } 74 | { a: N, b: N, c: 0 } 75 | { a: N, b: N, c: 1 } 76 | { a: N, b: N, c: 2 }; 77 declare let s: S; 78 declare let t: T; 79 80 // S *should* be assignable but the number of 81 // combinations is too complex. 82 t = s; 83} 84 85// https://github.com/Microsoft/TypeScript/issues/14865 86namespace GH14865 { 87 type Style1 = { 88 type: "A"; 89 data: string; 90 } | { 91 type: "B"; 92 data: string; 93 }; 94 95 type Style2 = { 96 type: "A" | "B"; 97 data: string; 98 } 99 100 const a: Style2 = { type: "A", data: "whatevs" }; 101 let b: Style1; 102 a.type; // "A" | "B" 103 b.type; // "A" | "B" 104 b = a; // should be assignable 105} 106 107// https://github.com/Microsoft/TypeScript/issues/30170 108namespace GH30170 { 109 interface Blue { 110 color: 'blue' 111 } 112 interface Yellow { 113 color?: 'yellow', 114 } 115 function draw(val: Blue | Yellow) { } 116 117 function drawWithColor(currentColor: 'blue' | 'yellow' | undefined) { 118 return draw({ color: currentColor }); 119 } 120} 121 122// https://github.com/Microsoft/TypeScript/issues/12052 123namespace GH12052 { 124 interface ILinearAxis { type: "linear"; } 125 126 interface ICategoricalAxis { type: "categorical"; } 127 128 type IAxis = ILinearAxis | ICategoricalAxis; 129 type IAxisType = "linear" | "categorical"; 130 131 function getAxisType(): IAxisType { 132 if (1 == 1) { 133 return "categorical"; 134 } else { 135 return "linear"; 136 } 137 } 138 139 const bad: IAxis = { type: getAxisType() }; 140 const good: IAxis = { type: undefined }; 141 good.type = getAxisType(); 142} 143 144// https://github.com/Microsoft/TypeScript/issues/18421 145namespace GH18421 { 146 interface ThingTypeOne { 147 type: 'one'; 148 } 149 150 interface ThingTypeTwo { 151 type: 'two'; 152 } 153 154 type ThingType = 'one' | 'two'; 155 156 type Thing = ThingTypeOne | ThingTypeTwo; 157 158 function makeNewThing(thingType: ThingType): Thing { 159 return { 160 type: thingType 161 }; 162 } 163} 164 165// https://github.com/Microsoft/TypeScript/issues/15907 166namespace GH15907 { 167 type Action = { type: 'activate' } | { type: 'disactivate' }; 168 169 function dispatchAction(action: Action): void { 170 171 } 172 173 const active = true; 174 175 dispatchAction({ type : (active? 'disactivate' : 'activate') }); 176} 177 178// https://github.com/Microsoft/TypeScript/issues/20889 179namespace GH20889 { 180 interface A1 { 181 type: "A1"; 182 } 183 interface A2 { 184 type: "A2"; 185 } 186 type AU = A1 | A2; 187 188 function foo(obj1: AU) { 189 const obj2: AU = { 190 type: obj1.type 191 }; 192 } 193} 194 195// https://github.com/microsoft/TypeScript/issues/39357 196namespace GH39357 { 197 type A = ["a", number] | ["b", number] | ["c", string]; 198 type B = "a" | "b" | "c"; 199 declare const b: B; 200 const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""]; 201} 202