Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jablko committed Jan 25, 2020
1 parent b47f3d9 commit f67c607
Show file tree
Hide file tree
Showing 9 changed files with 1,659 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(14,22): error TS2345: Argument of type '"value"' is not assignable to parameter of type 'XX extends XX ? "value" : never'.
Type '"value"' is not assignable to type 'never'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(32,20): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(33,21): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(37,24): error TS2345: Argument of type 'T | null' is not assignable to parameter of type 'null extends T | null ? any : never'.
Type 'null' is not assignable to type 'null extends T | null ? any : never'.
Type 'null' is not assignable to type 'never'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(43,5): error TS2322: Type '{ x: T; y: T; }' is not assignable to type 'T extends T ? { x: T; y: T; } : never'.
Type '{ x: T; y: T; }' is not assignable to type 'never'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(50,5): error TS2322: Type 'string' is not assignable to type 'Foo<T>'.
Type 'string' is not assignable to type '"a"'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(64,11): error TS2322: Type '[T] extends [string] ? { y: number; } : { a: number; b: number; }' is not assignable to type '[T] extends [number] ? [T] extends [string] ? { y: number; } : { a: number; } : [T] extends [string] ? { y: number; } : { b: number; }'.
Type '{ y: number; } | { a: number; b: number; }' is not assignable to type '[T] extends [number] ? [T] extends [string] ? { y: number; } : { a: number; } : [T] extends [string] ? { y: number; } : { b: number; }'.
Type '{ y: number; }' is not assignable to type '[T] extends [number] ? [T] extends [string] ? { y: number; } : { a: number; } : [T] extends [string] ? { y: number; } : { b: number; }'.
Type '{ y: number; }' is not assignable to type '([T] extends [string] ? { y: number; } : { a: number; }) & ([T] extends [string] ? { y: number; } : { b: number; })'.
Type '{ y: number; }' is not assignable to type '[T] extends [string] ? { y: number; } : { a: number; }'.
Type '{ y: number; }' is not assignable to type '{ y: number; } & { a: number; }'.
Property 'a' is missing in type '{ y: number; }' but required in type '{ a: number; }'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(111,5): error TS2322: Type 'Q' is not assignable to type 'InferBecauseWhyNot<Q>'.
Type '(arg: any) => any' is not assignable to type 'InferBecauseWhyNot<Q>'.
Type '(arg: any) => any' is not assignable to type 'never'.
Type 'Q' is not assignable to type 'never'.
Type '(arg: any) => any' is not assignable to type 'never'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(131,1): error TS2322: Type 'true' is not assignable to type 'false'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(132,1): error TS2322: Type 'false' is not assignable to type 'true'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(136,1): error TS2322: Type 'false' is not assignable to type 'true'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(137,1): error TS2322: Type 'true' is not assignable to type 'false'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(147,5): error TS2322: Type 'T extends "a" ? true : false' is not assignable to type 'false'.
Type 'boolean' is not assignable to type 'false'.
Type 'true' is not assignable to type 'false'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(148,5): error TS2322: Type 'T extends "b" ? true : false' is not assignable to type 'true'.
Type 'boolean' is not assignable to type 'true'.
Type 'false' is not assignable to type 'true'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(152,5): error TS2322: Type 'false' is not assignable to type 'T extends "a" ? true : false'.
Type 'false' is not assignable to type 'never'.
Type 'false' is not assignable to type 'true'.
tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts(153,5): error TS2322: Type 'true' is not assignable to type 'T extends "b" ? true : false'.
Type 'true' is not assignable to type 'never'.
Type 'true' is not assignable to type 'false'.


==== tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts (16 errors) ====
// #29505

export type FilterPropsByType<T, TT> = {
[K in keyof T]: T[K] extends TT ? K : never
}[keyof T];

function select<
T extends string | number,
TList extends object,
TValueProp extends FilterPropsByType<TList, T>
>(property: T, list: TList[], valueProp: TValueProp) {}

<XX extends string>(x: XX, tipos: { value: XX }[]) => {
select(x, tipos, "value");
~~~~~~~
!!! error TS2345: Argument of type '"value"' is not assignable to parameter of type 'XX extends XX ? "value" : never'.
!!! error TS2345: Type '"value"' is not assignable to type 'never'.
};

// #29662

declare function onlyNullablePlease<T extends null extends T ? any : never>(
value: T
): void;

declare function onlyNullablePlease2<
T extends [null] extends [T] ? any : never
>(value: T): void;

declare var z: string | null;
onlyNullablePlease(z); // works as expected
onlyNullablePlease2(z); // works as expected

declare var y: string;
onlyNullablePlease(y); // error as expected
~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
onlyNullablePlease2(y); // error as expected
~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.

<T>(t: T) => {
var x: T | null = Math.random() > 0.5 ? null : t;
onlyNullablePlease(x); // should work
~
!!! error TS2345: Argument of type 'T | null' is not assignable to parameter of type 'null extends T | null ? any : never'.
!!! error TS2345: Type 'null' is not assignable to type 'null extends T | null ? any : never'.
!!! error TS2345: Type 'null' is not assignable to type 'never'.
onlyNullablePlease2(x); // should work
};

<T>(t1: { x: T; y: T }, t2: T extends T ? { x: T; y: T } : never) => {
t1 = t2; // OK
t2 = t1; // should fail
~~
!!! error TS2322: Type '{ x: T; y: T; }' is not assignable to type 'T extends T ? { x: T; y: T; } : never'.
!!! error TS2322: Type '{ x: T; y: T; }' is not assignable to type 'never'.
};

type Foo<T> = T extends true ? string : "a";

<T>(x: Foo<T>, s: string) => {
x = "a"; // Currently an error, should be ok
x = s; // Error
~
!!! error TS2322: Type 'string' is not assignable to type 'Foo<T>'.
!!! error TS2322: Type 'string' is not assignable to type '"a"'.
};

// #26933

type Distributive<T> = T extends { a: number } ? { a: number } : { b: number };
<T>() => {
const o = { a: 1, b: 2 };
const x: [T] extends [string]
? { y: number }
: { a: number; b: number } = undefined!;
// Simple case: OK
const o1: [T] extends [number] ? { a: number } : { b: number } = o;
// Simple case where source happens to be a conditional type: also OK
const x1: [T] extends [number]
~~
!!! error TS2322: Type '[T] extends [string] ? { y: number; } : { a: number; b: number; }' is not assignable to type '[T] extends [number] ? [T] extends [string] ? { y: number; } : { a: number; } : [T] extends [string] ? { y: number; } : { b: number; }'.
!!! error TS2322: Type '{ y: number; } | { a: number; b: number; }' is not assignable to type '[T] extends [number] ? [T] extends [string] ? { y: number; } : { a: number; } : [T] extends [string] ? { y: number; } : { b: number; }'.
!!! error TS2322: Type '{ y: number; }' is not assignable to type '[T] extends [number] ? [T] extends [string] ? { y: number; } : { a: number; } : [T] extends [string] ? { y: number; } : { b: number; }'.
!!! error TS2322: Type '{ y: number; }' is not assignable to type '([T] extends [string] ? { y: number; } : { a: number; }) & ([T] extends [string] ? { y: number; } : { b: number; })'.
!!! error TS2322: Type '{ y: number; }' is not assignable to type '[T] extends [string] ? { y: number; } : { a: number; }'.
!!! error TS2322: Type '{ y: number; }' is not assignable to type '{ y: number; } & { a: number; }'.
!!! error TS2322: Property 'a' is missing in type '{ y: number; }' but required in type '{ a: number; }'.
!!! related TS2728 tests/cases/compiler/conditionalTypeAssignabilityWhenDeferred.ts:65:53: 'a' is declared here.
? ([T] extends [string] ? { y: number } : { a: number })
: ([T] extends [string] ? { y: number } : { b: number }) = x;
// Infer type parameters: no good
const o2: [T] extends [[infer U]] ? U : { b: number } = o;

// The next 4 are arguable - if you choose to ignore the `never` distribution case,
// then they're all good. The `never` case _is_ a bit of an outlier - we say distributive types
// look approximately like the sum of their branches, but the `never` case bucks that.
// There's an argument for the result of dumping `never` into a distributive conditional
// being not `never`, but instead the intersection of the branches - a much more precise bound
// on that "impossible" input.

// Distributive where T might instantiate to never: no good
const o3: Distributive<T> = o;
// Distributive where T & string might instantiate to never: also no good
const o4: Distributive<T & string> = o;
// Distributive where {a: T} cannot instantiate to never: OK
const o5: Distributive<{ a: T }> = o;
// Distributive where check type is a conditional which returns a non-never type upon instantiation with `never` but can still return never otherwise: no good
const o6: Distributive<[T] extends [never] ? { a: number } : never> = o;
};

type Wrapped<T> = { ___secret: T };
type Unwrap<T> = T extends Wrapped<infer U> ? U : T;

declare function set<T, K extends keyof T>(
obj: T,
key: K,
value: Unwrap<T[K]>
): Unwrap<T[K]>;

class Foo2 {
prop!: Wrapped<string>;

method() {
set(this, "prop", "hi"); // <-- type error
}
}

set(new Foo2(), "prop", "hi"); // <-- typechecks

type InferBecauseWhyNot<T> = [T] extends [(p: infer P1) => any]
? P1 | T
: never;

<Q extends (arg: any) => any>(x: Q): InferBecauseWhyNot<Q> => {
return x;
~~~~~~~~~
!!! error TS2322: Type 'Q' is not assignable to type 'InferBecauseWhyNot<Q>'.
!!! error TS2322: Type '(arg: any) => any' is not assignable to type 'InferBecauseWhyNot<Q>'.
!!! error TS2322: Type '(arg: any) => any' is not assignable to type 'never'.
!!! error TS2322: Type 'Q' is not assignable to type 'never'.
!!! error TS2322: Type '(arg: any) => any' is not assignable to type 'never'.
};

type InferBecauseWhyNotDistributive<T> = T extends (p: infer P1) => any
? P1 | T
: never;

<Q extends (arg: any) => any>(
x: Q
): InferBecauseWhyNotDistributive<Q> => {
return x; // should fail
};

let t: true = undefined!;
let f: false = undefined!;

let a: "a" extends "a" ? true : false = undefined!;
let b: "a" extends "b" ? true : false = undefined!;

t = a;
f = a; // !!! error TS2322: Type 'true' is not assignable to type 'false'.
~
!!! error TS2322: Type 'true' is not assignable to type 'false'.
t = b; // !!! error TS2322: Type 'false' is not assignable to type 'true'.
~
!!! error TS2322: Type 'false' is not assignable to type 'true'.
f = b;

a = t;
a = f; // !!! error TS2322: Type 'false' is not assignable to type 'true'.
~
!!! error TS2322: Type 'false' is not assignable to type 'true'.
b = t; // !!! error TS2322: Type 'true' is not assignable to type 'false'.
~
!!! error TS2322: Type 'true' is not assignable to type 'false'.
b = f;

// #23132

<T extends "a">() => {
let a: T extends "a" ? true : false = undefined!;
let b: T extends "b" ? true : false = undefined!;

t = a;
f = a; // !!! error TS2322: Type 'T extends "a" ? true : false' is not assignable to type 'false'.
~
!!! error TS2322: Type 'T extends "a" ? true : false' is not assignable to type 'false'.
!!! error TS2322: Type 'boolean' is not assignable to type 'false'.
!!! error TS2322: Type 'true' is not assignable to type 'false'.
t = b; // !!! error TS2322: Type 'T extends "b" ? true : false' is not assignable to type 'true'.
~
!!! error TS2322: Type 'T extends "b" ? true : false' is not assignable to type 'true'.
!!! error TS2322: Type 'boolean' is not assignable to type 'true'.
!!! error TS2322: Type 'false' is not assignable to type 'true'.
f = b;

a = t;
a = f; // !!! error TS2322: Type 'false' is not assignable to type 'T extends "a" ? true : false'.
~
!!! error TS2322: Type 'false' is not assignable to type 'T extends "a" ? true : false'.
!!! error TS2322: Type 'false' is not assignable to type 'never'.
!!! error TS2322: Type 'false' is not assignable to type 'true'.
b = t; // !!! error TS2322: Type 'true' is not assignable to type 'T extends "b" ? true : false'.
~
!!! error TS2322: Type 'true' is not assignable to type 'T extends "b" ? true : false'.
!!! error TS2322: Type 'true' is not assignable to type 'never'.
!!! error TS2322: Type 'true' is not assignable to type 'false'.
b = f;
};

Loading

0 comments on commit f67c607

Please sign in to comment.