Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add tests
  • Loading branch information
ahejlsberg committed Oct 15, 2021
commit 939b5b44f22745f4192cb0807cad6c3bc14bb21e
74 changes: 74 additions & 0 deletions tests/baselines/reference/coAndContraVariantInferences.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//// [coAndContraVariantInferences.ts]
type A = { kind: 'a' };
type B = { kind: 'b' };

declare const a: A;
declare const b: B;

declare function fab(arg: A | B): void;

declare function foo<T>(x: { kind: T }, f: (arg: { kind: T }) => void): void;

foo(a, fab);
foo(b, fab);

// Repro from #45603

interface Action<TName extends string,TPayload> {
name: TName,
payload: TPayload
}

const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>;
const actionB = { payload: true } as Action<'ACTION_B', boolean>;

function call<TName extends string,TPayload>(
action: Action<TName,TPayload>,
fn: (action: Action<TName,TPayload>)=> any,
) {
fn(action);
}

const printFn = (action: typeof actionA | typeof actionB)=> console.log(action);

call(actionA, printFn);
call(actionB, printFn);


//// [coAndContraVariantInferences.js]
"use strict";
foo(a, fab);
foo(b, fab);
var actionA = { payload: 'any-string' };
var actionB = { payload: true };
function call(action, fn) {
fn(action);
}
var printFn = function (action) { return console.log(action); };
call(actionA, printFn);
call(actionB, printFn);


//// [coAndContraVariantInferences.d.ts]
declare type A = {
kind: 'a';
};
declare type B = {
kind: 'b';
};
declare const a: A;
declare const b: B;
declare function fab(arg: A | B): void;
declare function foo<T>(x: {
kind: T;
}, f: (arg: {
kind: T;
}) => void): void;
interface Action<TName extends string, TPayload> {
name: TName;
payload: TPayload;
}
declare const actionA: Action<"ACTION_A", string>;
declare const actionB: Action<"ACTION_B", boolean>;
declare function call<TName extends string, TPayload>(action: Action<TName, TPayload>, fn: (action: Action<TName, TPayload>) => any): void;
declare const printFn: (action: typeof actionA | typeof actionB) => void;
114 changes: 114 additions & 0 deletions tests/baselines/reference/coAndContraVariantInferences.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
=== tests/cases/compiler/coAndContraVariantInferences.ts ===
type A = { kind: 'a' };
>A : Symbol(A, Decl(coAndContraVariantInferences.ts, 0, 0))
>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 0, 10))

type B = { kind: 'b' };
>B : Symbol(B, Decl(coAndContraVariantInferences.ts, 0, 23))
>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 1, 10))

declare const a: A;
>a : Symbol(a, Decl(coAndContraVariantInferences.ts, 3, 13))
>A : Symbol(A, Decl(coAndContraVariantInferences.ts, 0, 0))

declare const b: B;
>b : Symbol(b, Decl(coAndContraVariantInferences.ts, 4, 13))
>B : Symbol(B, Decl(coAndContraVariantInferences.ts, 0, 23))

declare function fab(arg: A | B): void;
>fab : Symbol(fab, Decl(coAndContraVariantInferences.ts, 4, 19))
>arg : Symbol(arg, Decl(coAndContraVariantInferences.ts, 6, 21))
>A : Symbol(A, Decl(coAndContraVariantInferences.ts, 0, 0))
>B : Symbol(B, Decl(coAndContraVariantInferences.ts, 0, 23))

declare function foo<T>(x: { kind: T }, f: (arg: { kind: T }) => void): void;
>foo : Symbol(foo, Decl(coAndContraVariantInferences.ts, 6, 39))
>T : Symbol(T, Decl(coAndContraVariantInferences.ts, 8, 21))
>x : Symbol(x, Decl(coAndContraVariantInferences.ts, 8, 24))
>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 8, 28))
>T : Symbol(T, Decl(coAndContraVariantInferences.ts, 8, 21))
>f : Symbol(f, Decl(coAndContraVariantInferences.ts, 8, 39))
>arg : Symbol(arg, Decl(coAndContraVariantInferences.ts, 8, 44))
>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 8, 50))
>T : Symbol(T, Decl(coAndContraVariantInferences.ts, 8, 21))

foo(a, fab);
>foo : Symbol(foo, Decl(coAndContraVariantInferences.ts, 6, 39))
>a : Symbol(a, Decl(coAndContraVariantInferences.ts, 3, 13))
>fab : Symbol(fab, Decl(coAndContraVariantInferences.ts, 4, 19))

foo(b, fab);
>foo : Symbol(foo, Decl(coAndContraVariantInferences.ts, 6, 39))
>b : Symbol(b, Decl(coAndContraVariantInferences.ts, 4, 13))
>fab : Symbol(fab, Decl(coAndContraVariantInferences.ts, 4, 19))

// Repro from #45603

interface Action<TName extends string,TPayload> {
>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12))
>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 15, 17))
>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 15, 38))

name: TName,
>name : Symbol(Action.name, Decl(coAndContraVariantInferences.ts, 15, 49))
>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 15, 17))

payload: TPayload
>payload : Symbol(Action.payload, Decl(coAndContraVariantInferences.ts, 16, 16))
>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 15, 38))
}

const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>;
>actionA : Symbol(actionA, Decl(coAndContraVariantInferences.ts, 20, 5))
>payload : Symbol(payload, Decl(coAndContraVariantInferences.ts, 20, 17))
>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12))

const actionB = { payload: true } as Action<'ACTION_B', boolean>;
>actionB : Symbol(actionB, Decl(coAndContraVariantInferences.ts, 21, 5))
>payload : Symbol(payload, Decl(coAndContraVariantInferences.ts, 21, 17))
>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12))

function call<TName extends string,TPayload>(
>call : Symbol(call, Decl(coAndContraVariantInferences.ts, 21, 65))
>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 23, 14))
>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 23, 35))

action: Action<TName,TPayload>,
>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 23, 45))
>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12))
>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 23, 14))
>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 23, 35))

fn: (action: Action<TName,TPayload>)=> any,
>fn : Symbol(fn, Decl(coAndContraVariantInferences.ts, 24, 33))
>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 25, 7))
>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12))
>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 23, 14))
>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 23, 35))

) {
fn(action);
>fn : Symbol(fn, Decl(coAndContraVariantInferences.ts, 24, 33))
>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 23, 45))
}

const printFn = (action: typeof actionA | typeof actionB)=> console.log(action);
>printFn : Symbol(printFn, Decl(coAndContraVariantInferences.ts, 30, 5))
>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 30, 17))
>actionA : Symbol(actionA, Decl(coAndContraVariantInferences.ts, 20, 5))
>actionB : Symbol(actionB, Decl(coAndContraVariantInferences.ts, 21, 5))
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 30, 17))

call(actionA, printFn);
>call : Symbol(call, Decl(coAndContraVariantInferences.ts, 21, 65))
>actionA : Symbol(actionA, Decl(coAndContraVariantInferences.ts, 20, 5))
>printFn : Symbol(printFn, Decl(coAndContraVariantInferences.ts, 30, 5))

call(actionB, printFn);
>call : Symbol(call, Decl(coAndContraVariantInferences.ts, 21, 65))
>actionB : Symbol(actionB, Decl(coAndContraVariantInferences.ts, 21, 5))
>printFn : Symbol(printFn, Decl(coAndContraVariantInferences.ts, 30, 5))

104 changes: 104 additions & 0 deletions tests/baselines/reference/coAndContraVariantInferences.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
=== tests/cases/compiler/coAndContraVariantInferences.ts ===
type A = { kind: 'a' };
>A : A
>kind : "a"

type B = { kind: 'b' };
>B : B
>kind : "b"

declare const a: A;
>a : A

declare const b: B;
>b : B

declare function fab(arg: A | B): void;
>fab : (arg: A | B) => void
>arg : A | B

declare function foo<T>(x: { kind: T }, f: (arg: { kind: T }) => void): void;
>foo : <T>(x: { kind: T;}, f: (arg: { kind: T;}) => void) => void
>x : { kind: T; }
>kind : T
>f : (arg: { kind: T;}) => void
>arg : { kind: T; }
>kind : T

foo(a, fab);
>foo(a, fab) : void
>foo : <T>(x: { kind: T; }, f: (arg: { kind: T; }) => void) => void
>a : A
>fab : (arg: A | B) => void

foo(b, fab);
>foo(b, fab) : void
>foo : <T>(x: { kind: T; }, f: (arg: { kind: T; }) => void) => void
>b : B
>fab : (arg: A | B) => void

// Repro from #45603

interface Action<TName extends string,TPayload> {
name: TName,
>name : TName

payload: TPayload
>payload : TPayload
}

const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>;
>actionA : Action<"ACTION_A", string>
>{ payload: 'any-string' } as Action<'ACTION_A', string> : Action<"ACTION_A", string>
>{ payload: 'any-string' } : { payload: string; }
>payload : string
>'any-string' : "any-string"

const actionB = { payload: true } as Action<'ACTION_B', boolean>;
>actionB : Action<"ACTION_B", boolean>
>{ payload: true } as Action<'ACTION_B', boolean> : Action<"ACTION_B", boolean>
>{ payload: true } : { payload: true; }
>payload : true
>true : true

function call<TName extends string,TPayload>(
>call : <TName extends string, TPayload>(action: Action<TName, TPayload>, fn: (action: Action<TName, TPayload>) => any) => void

action: Action<TName,TPayload>,
>action : Action<TName, TPayload>

fn: (action: Action<TName,TPayload>)=> any,
>fn : (action: Action<TName, TPayload>) => any
>action : Action<TName, TPayload>

) {
fn(action);
>fn(action) : any
>fn : (action: Action<TName, TPayload>) => any
>action : Action<TName, TPayload>
}

const printFn = (action: typeof actionA | typeof actionB)=> console.log(action);
>printFn : (action: typeof actionA | typeof actionB) => void
>(action: typeof actionA | typeof actionB)=> console.log(action) : (action: typeof actionA | typeof actionB) => void
>action : Action<"ACTION_A", string> | Action<"ACTION_B", boolean>
>actionA : Action<"ACTION_A", string>
>actionB : Action<"ACTION_B", boolean>
>console.log(action) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>action : Action<"ACTION_A", string> | Action<"ACTION_B", boolean>

call(actionA, printFn);
>call(actionA, printFn) : void
>call : <TName extends string, TPayload>(action: Action<TName, TPayload>, fn: (action: Action<TName, TPayload>) => any) => void
>actionA : Action<"ACTION_A", string>
>printFn : (action: Action<"ACTION_A", string> | Action<"ACTION_B", boolean>) => void

call(actionB, printFn);
>call(actionB, printFn) : void
>call : <TName extends string, TPayload>(action: Action<TName, TPayload>, fn: (action: Action<TName, TPayload>) => any) => void
>actionB : Action<"ACTION_B", boolean>
>printFn : (action: Action<"ACTION_A", string> | Action<"ACTION_B", boolean>) => void

37 changes: 37 additions & 0 deletions tests/cases/compiler/coAndContraVariantInferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// @strict: true
// @declaration: true

type A = { kind: 'a' };
type B = { kind: 'b' };

declare const a: A;
declare const b: B;

declare function fab(arg: A | B): void;

declare function foo<T>(x: { kind: T }, f: (arg: { kind: T }) => void): void;

foo(a, fab);
foo(b, fab);

// Repro from #45603

interface Action<TName extends string,TPayload> {
name: TName,
payload: TPayload
}

const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>;
const actionB = { payload: true } as Action<'ACTION_B', boolean>;

function call<TName extends string,TPayload>(
action: Action<TName,TPayload>,
fn: (action: Action<TName,TPayload>)=> any,
) {
fn(action);
}

const printFn = (action: typeof actionA | typeof actionB)=> console.log(action);

call(actionA, printFn);
call(actionB, printFn);