These tests do not pass ATM. But hopefully will in the future 🤞
function getProperty(property: "a" | "b" | "c") {
return { a: 1, b: 2, c: 3 }[property]
}
getProperty("d")
getProperty("c") satisfies 2
- Expected "a" | "b" | "c" found "d"
- Expected 2 found 3
function map<T, U>(a: T, b: (t: T) => U) {
return b(a)
}
map(2, Math.sin)
map("string", Math.sin)
- Argument of type "string" is not assignable to parameter of type number
Because
Math.sin
set T to number
type Func1 = () => 3;
type Func2 = () => 2;
function callFunc<T, U>(func: (() => T) | (() => U)): 3 | 2 {
return func()
}
print_type(callFunc)
- Expected "a" | "b" | "c" found "d"
function or<T, U>(obj: T | U): U | T {
return obj
}
print_type(or)
- Expected "a" | "b" | "c" found "d"
function and<T, U>(obj: T & U): U & T {
return obj
}
print_type(and)
- Expected "a" | "b" | "c" found "d"
function distribute<T, U, V>(obj: (T | U) & V): (T & V) | (U & V) {
return obj
}
print_type(distribute)
- Expected "a" | "b" | "c" found "d"
function get(obj: {a: 2} | { b: 3 }) {
return obj.a
}
- Expected "a" | "b" | "c" found "d"
function callFunc<T, U>(func: (() => T) | (() => U)): T | U {
return func()
}
print_type(callFunc)
- Expected string, found (obj: { prop: 3 } | { prop: 2 }) => 3 | 2
Too many generics here, doesn't get caught for some reason?
let c: Array<number> = []
function add() {
c.push("hi")
}
- Type "hi" is not assignable to argument of type number
interface MyObject {
a(b: string): any;
}
const obj: MyObject = {
a(b) {
print_type(b)
}
}
- TODO?
TODO
typeof
,instanceof
, conditional, across a function
declare let a: string;
if (a === "hi") {
a satisfies "hello"
}
- Expected "hello", found "hi"
function ChangeThis(this: { value: any }) {
return this.value
}
const x = ChangeThis.bind({ value: 2 })
x() satisfies 3
- Expected 3, found 2
let properties: string = "";
for (const property in { a: 1, b: 2, c: 3 }) {
properties += property;
}
properties satisfies boolean;
- Expected boolean, found "abc"
TypeScript anonymous object annotations do not guarantee ordering and the subtyping rules allow for the RHS to have more properties than defined
declare const myObject: { a: 1, b: 2, c: 3 };
let properties: string = "";
for (const property in myObject) {
properties += property;
}
properties satisfies boolean;
- Expected boolean, found string
TODO for in and generators
function func(array: Array<string>) {
for (const item of array) {
item satisfies number
}
}
- Expected number found string
function join(array: Array<string>) {
let buf = ""
for (let item of array) {
buf += item
}
return buf
}
join(["a", "b", "c"]) satisfies "cba"
- Expected "cba" found "abc"
Although this is valid JS, it is currently assumed that this is beneficial behavior
function x(p) {
return p.b
}
x satisfies string;
- Expected string, found (p: { b: any }) => any
function ChangeThis() {
return this.value
}
- TODO
let x = "hi"
function call() {
return Math.cos(x)
}
call()
x = 0
call() satisfies 2
- Cannot call TODO
- Expected 2 found 1
function call(prop) {
return { a: 1, b: 2, c: 3 }[prop]
}
print_type(call)
- (prop: "a" | "b" | "c") => number
TODO Promise properties
async function x() {
return 2
}
x satisfies string;
- Expected string, found Promise { 2 }
async function x() {
return 2
}
(await x) satisfies string;
- Expected string, found 2
declare let a: Promise<string>;
(await a) satisfies number
- Expected number, found string
function x*() {
return 2
}
(await x) satisfies string;
- TODO
TODO effects, different traps and
Object.defineProperty
const a = new Proxy({ prop: 2 })
a.prop satisfies 3
- Expected 3, found 2
const a = new Proxy({ }, { get(prop) { return prop } })
a.prop1 satisfies "prop1"
a.prop3 satisfies "prop2"
- Expected "prop2", found "prop3"
TODO filter, every and all, find, etc
function mapper(a: Array<string>) {
return a.map(item => item + "hi")
}
print_type(mapper)
- TODO
function mapper<T, U>(a: Array<T>, func: T => U) {
return a.map(func)
}
print_type(mapper)
- TODO
This is allowed under non strict casts option (and will return NaN) but the tests run with strict casts on
This would need to support [Symbol.toPrimitive] + a bunch of error handling
console + 2
- Expected number, found Console
const array1 = [1, 2, 3];
const array2 = [...array1, 4, 5, 6];
array2.length satisfies 6;
array2[2] satisfies string;
- Expected string, found 3
TODO include an object destructure here
let array1 = [1, 2, 3];
let a = 0, b = 0;
[a, b] = array1;
a satisfies 1;
b satisfies "hello world";
- Expected "hello world", found 2
TODO needs
Logical
-ishPropertyValue
declare const global: { a?: string };
("a" in global) satisfies string;
(global.a) satisfies 2;
- Expected string, found boolean
- Expected 2, found string | undefined
declare let global: { a?: string, b: string };
// Fine
delete global.a;
// Bad
delete global.b;
- Cannot delete property "b" off { a?: string, b: string }
try {
throw 2;
} catch (e: string) {
// ...
}
- Thrown type 2, not assignable to catch variable of string
TODO better test
(typeof "hello") satisfies "string";
(typeof 5) satisfies "number";
(typeof {}) satisfies "Number";
- Expected "Number", found "object"
class X {}
class Y {}
(new X instanceof X) satisfies number;
(new X instanceof Y) satisfies false;
- Expected number, found true
let x: number = 0;
document.addEventListener("click", () => {
x++;
});
document.addEventListener("scroll", () => {
x satisfies 0;
x++;
})
- Expected 0, found number
class BaseClass extends class { x: 2 } {
y: 3
}
const b = new BaseClass;
print_type(b.x);
- TODO
class MyClass {
#a = 2;
getA(this: { #a: any }) {
return this.#a
}
}
(new MyClass).#a;
((new MyClass).getA() satisfies 3);
- Cannot get private property "#a"
- Expected 3, found 2
function x(a: number) {
if (a > 10 || a < 0) {
return a
}
return a--
}
print_type(x(4))
print_type(x(90))
- TODO
function call(cb: () => void) {
return cb()
}
call(call)
- TODO hopefully doesn't blow up
I don't think this works because of fact combining
function doThing(a, b = (a += 2)) {
return a
}
doThing(3) satisfies 2;
doThing(6, 1) satisfies 6;
- Expected 2, found 5
function doThing(b: number = "hello") {
return a
}
- Default value "hello" is not assignable to parameter of type number