Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed Mar 10, 2021
1 parent 13cf64e commit a0fbf5c
Show file tree
Hide file tree
Showing 5 changed files with 926 additions and 0 deletions.
114 changes: 114 additions & 0 deletions tests/baselines/reference/controlFlowGenericTypes.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts(49,11): error TS2339: Property 'foo' does not exist on type 'MyUnion'.
Property 'foo' does not exist on type 'AA'.
tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts(58,44): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts(59,11): error TS2339: Property 'foo' does not exist on type 'MyUnion'.
Property 'foo' does not exist on type 'AA'.


==== tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts (3 errors) ====
function f1<T extends string | undefined>(x: T, y: { a: T }, z: [T]): string {
if (x) {
x;
x.length;
return x;
}
if (y.a) {
y.a.length;
return y.a;
}
if (z[0]) {
z[0].length;
return z[0];
}
return "hello";
}

function f2<T>(x: Extract<T, string | undefined> | null): string {
if (x) {
x;
x.length;
return x;
}
return "hello";
}

// Repro from #13995

declare function takeA(val: 'A'): void;
export function bounceAndTakeIfA<AB extends 'A' | 'B'>(value: AB): AB {
if (value === 'A') {
takeA(value);
return value;
}
else {
return value;
}
}

// Repro from #13995

type Common = { id: number };
type AA = { tag: 'A', id: number };
type BB = { tag: 'B', id: number, foo: number };

type MyUnion = AA | BB;

const fn = (value: MyUnion) => {
value.foo; // Error
~~~
!!! error TS2339: Property 'foo' does not exist on type 'MyUnion'.
!!! error TS2339: Property 'foo' does not exist on type 'AA'.
if ('foo' in value) {
value.foo;
}
if (value.tag === 'B') {
value.foo;
}
};

const fn2 = <T extends MyUnion>(value: T): MyUnion => {
~~~~~~~
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
value.foo; // Error
~~~
!!! error TS2339: Property 'foo' does not exist on type 'MyUnion'.
!!! error TS2339: Property 'foo' does not exist on type 'AA'.
if ('foo' in value) {
value.foo;
}
if (value.tag === 'B') {
value.foo;
}
};

// Repro from #13995

type A1 = {
testable: true
doTest: () => void
}
type B1 = {
testable: false
};

type Union = A1 | B1

function notWorking<T extends Union>(object: T) {
if (!object.testable) return;
object.doTest();
}

// Repro from #42939

interface A {
a: number | null;
};

function get<K extends keyof A>(key: K, obj: A): number {
const value = obj[key];
if (value !== null) {
return value;
}
return 0;
};

170 changes: 170 additions & 0 deletions tests/baselines/reference/controlFlowGenericTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
//// [controlFlowGenericTypes.ts]
function f1<T extends string | undefined>(x: T, y: { a: T }, z: [T]): string {
if (x) {
x;
x.length;
return x;
}
if (y.a) {
y.a.length;
return y.a;
}
if (z[0]) {
z[0].length;
return z[0];
}
return "hello";
}

function f2<T>(x: Extract<T, string | undefined> | null): string {
if (x) {
x;
x.length;
return x;
}
return "hello";
}

// Repro from #13995

declare function takeA(val: 'A'): void;
export function bounceAndTakeIfA<AB extends 'A' | 'B'>(value: AB): AB {
if (value === 'A') {
takeA(value);
return value;
}
else {
return value;
}
}

// Repro from #13995

type Common = { id: number };
type AA = { tag: 'A', id: number };
type BB = { tag: 'B', id: number, foo: number };

type MyUnion = AA | BB;

const fn = (value: MyUnion) => {
value.foo; // Error
if ('foo' in value) {
value.foo;
}
if (value.tag === 'B') {
value.foo;
}
};

const fn2 = <T extends MyUnion>(value: T): MyUnion => {
value.foo; // Error
if ('foo' in value) {
value.foo;
}
if (value.tag === 'B') {
value.foo;
}
};

// Repro from #13995

type A1 = {
testable: true
doTest: () => void
}
type B1 = {
testable: false
};

type Union = A1 | B1

function notWorking<T extends Union>(object: T) {
if (!object.testable) return;
object.doTest();
}

// Repro from #42939

interface A {
a: number | null;
};

function get<K extends keyof A>(key: K, obj: A): number {
const value = obj[key];
if (value !== null) {
return value;
}
return 0;
};


//// [controlFlowGenericTypes.js]
"use strict";
exports.__esModule = true;
exports.bounceAndTakeIfA = void 0;
function f1(x, y, z) {
if (x) {
x;
x.length;
return x;
}
if (y.a) {
y.a.length;
return y.a;
}
if (z[0]) {
z[0].length;
return z[0];
}
return "hello";
}
function f2(x) {
if (x) {
x;
x.length;
return x;
}
return "hello";
}
function bounceAndTakeIfA(value) {
if (value === 'A') {
takeA(value);
return value;
}
else {
return value;
}
}
exports.bounceAndTakeIfA = bounceAndTakeIfA;
var fn = function (value) {
value.foo; // Error
if ('foo' in value) {
value.foo;
}
if (value.tag === 'B') {
value.foo;
}
};
var fn2 = function (value) {
value.foo; // Error
if ('foo' in value) {
value.foo;
}
if (value.tag === 'B') {
value.foo;
}
};
function notWorking(object) {
if (!object.testable)
return;
object.doTest();
}
;
function get(key, obj) {
var value = obj[key];
if (value !== null) {
return value;
}
return 0;
}
;
Loading

0 comments on commit a0fbf5c

Please sign in to comment.