Skip to content

Commit

Permalink
Generic chain and others generic fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kaleidawave committed Mar 20, 2024
1 parent a63bcc0 commit b6e9b80
Show file tree
Hide file tree
Showing 30 changed files with 1,091 additions and 628 deletions.
125 changes: 63 additions & 62 deletions checker/definitions/full.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
@Constant
declare function debug_type_independent(t: any): void;

declare class Array<T> {
[index: number]: T | undefined;

Expand Down Expand Up @@ -30,55 +33,55 @@ declare class Array<T> {
}

// // TODO any is debatable
// filter(cb: (t: T, i?: number) => any): Array<T> {
// const { length } = this, filtered: Array<T> = [];
// let i: number = 0;
// while (i < length) {
// const value = this[i];
// if (cb(value, i++)) {
// filtered.push(value)
// }
// }
// return filtered;
// }
filter(cb: (t: T, i?: number) => any): Array<T> {
const { length } = this, filtered: Array<T> = [];
let i: number = 0;
while (i < length) {
const value = this[i];
if (cb(value, i++)) {
filtered.push(value)
}
}
return filtered;
}

// // TODO any is debatable
// find(cb: (t: T, i?: number) => any): T | undefined {
// const { length } = this;
// let i: number = 0;
// while (i < length) {
// const value = this[i];
// if (cb(value, i++)) {
// return value
// }
// }
// }
// TODO any is debatable
find(cb: (t: T, i?: number) => any): T | undefined {
const { length } = this;
let i: number = 0;
while (i < length) {
const value = this[i];
if (cb(value, i++)) {
return value
}
}
}

// // TODO any is debatable
// every(cb: (t: T, i?: number) => any): boolean {
// const { length } = this;
// let i: number = 0;
// while (i < length) {
// const value = this[i];
// if (!cb(value, i++)) {
// return false
// }
// }
// // Vacuous truth
// return true
// }
// TODO any is debatable
every(cb: (t: T, i?: number) => any): boolean {
const { length } = this;
let i: number = 0;
while (i < length) {
const value = this[i];
if (!cb(value, i++)) {
return false
}
}
// Vacuous truth
return true
}

// some(cb: (t: T, i?: number) => any): boolean {
// const { length } = this;
// let i: number = 0;
// while (i < length) {
// const value = this[i];
// if (cb(value, i++)) {
// return true
// }
// }
// return false
// }
some(cb: (t: T, i?: number) => any): boolean {
const { length } = this;
let i: number = 0;
while (i < length) {
const value = this[i];
if (cb(value, i++)) {
return true
}
}
return false
}

// includes(searchElement: T, fromIndex?: number): boolean {
// const { length } = this;
Expand All @@ -92,20 +95,20 @@ declare class Array<T> {
// return false
// }

// join(joiner?: string): string {
// const j = joiner ?? ",";
// const { length } = this;
// let i = 1;
// if (length === 0) {
// return ""
// }
// let s: string = "" + this[0];
// while (i < length) {
// s += j;
// s += this[i++];
// }
// return s
// }
join(joiner: string = ","): string {
const { length } = this;
let i: number = 1;
if (length === 0) {
return ""
}
let s: string = "" + this[0];
while (i < length) {
s += joiner;
s += this[i++];
// debug_type_independent(s)
}
return s
}
}

declare class Math {
Expand Down Expand Up @@ -231,8 +234,6 @@ declare function debug_type(t: any): void;
@Constant
declare function print_and_debug_type(t: any): void;
@Constant
declare function debug_type_independent(t: any): void;
@Constant
declare function debug_type_rust(t: any): void;
@Constant
declare function debug_type_rust_independent(t: any): void;
Expand Down
Binary file modified checker/definitions/internal.ts.d.bin
Binary file not shown.
Binary file removed checker/definitions/internal.ts.d2.bin
Binary file not shown.
28 changes: 9 additions & 19 deletions checker/specification/specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ const a = c

- Could not find variable 'c' in scope

#### Assigning before declaration

```ts
a = 3;
let a = 2;
```

- Cannot assign to variable 'a' before initialisation

#### Assignment to non-existent variable

```ts
Expand Down Expand Up @@ -864,25 +873,6 @@ function getObject(condition: boolean) {

- Expected string, found 4

#### Mutating an object by a function

> This is where the object loses its constant-ness
```ts
function doThingWithCallback(callback: (obj: { x: number }) => any) {
const obj: { x: number } = { x: 8 };
callback(obj);
(obj.x satisfies 8);
return obj;
}

const object = doThingWithCallback((obj: { x: number }) => obj.x = 2);
object.x satisfies string;
```

- Expected 8, found number
- Expected string, found 2

#### Assigning to parameter observed via effect

```ts
Expand Down
153 changes: 147 additions & 6 deletions checker/specification/staging.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,20 +191,36 @@ function func() {

### Classes

#### Hoisting of the type
#### Class type `extends`

```ts
function doThingWithClass(instance: Class1) {
class BaseClass {
b: boolean = false
}

class Class extends BaseClass {
a: number = 2
}

new Class().b satisfies 5
```

- Expected 5, found false

#### Hoisting of class type

```ts
function doThingWithClass(instance: Class) {
instance.prop satisfies string;
instance.parent_prop satisfies boolean;
instance.method(4);
}

class Class2 {
class BaseClass {
parent_prop: number
}

class Class1 extends Class2 {
class Class extends BaseClass {
prop: number

method(s: string) {}
Expand All @@ -215,6 +231,25 @@ class Class1 extends Class2 {
- Expected boolean, found number
- Argument of type 4 is not assignable to parameter of type string

#### Hoisting of class type with `extends`

```ts
function doThingWithClass(instance: Class) {
instance.a satisfies number;
instance.b satisfies string;
}

class BaseClass {
b: boolean
}

class Class extends BaseClass {
a: number
}
```

- Expected string, found boolean

### Overloads

#### Calling
Expand Down Expand Up @@ -260,7 +295,7 @@ stringIsHi(string) satisfies number;
```ts
type ExpectedFunction = () => ((a: string) => string)

const x: ExpectedFunction = function () {
const x: ExpectedFunction = function () {
return function (b) {
b satisfies number;
return b
Expand All @@ -270,14 +305,120 @@ const x: ExpectedFunction = function () {

- Expected number, found string

#### Computed generics from collection

```ts
const x = [1, 2, 3];
x.map(a => (a satisfies string, 2))
```

- Expected string, found 1 | 2 | 3

### Object constraints

#### Mutation by a function with unknown effects

> This is where the object loses its constant-ness
> Effectively raises it to the parameter type
```ts
function doThingWithCallback(callback: (obj: { prop: number }) => any) {
const obj = { prop: 8 };
callback(obj);
(obj.prop satisfies 8);
return obj;
}

const object = doThingWithCallback((obj: { prop: number }) => obj.prop = 2);
object.prop satisfies string;
```

- Expected 8, found number
- Expected string, found 2

#### Mutation negated via `readonly`

> This is where the object loses its constant-ness
```ts
function doThingWithCallback(callback: (obj: readonly { prop: number }) => any) {
const obj = { prop: 8 };
callback(obj);
(obj.prop satisfies 6);
}
```

- Expected 6, found 8

#### Possible mutation breaks object constraint

> This unfortunately can flag up valid code, but handling those is too difficult atm
```ts
function doThingWithCallback(callback: (obj: { prop: number | string }) => any) {
const obj: { prop: number } = { prop: 8 };
callback(obj);
}
```

- Cannot raise TODO. If possible avoid the constraints or mark parameter as readonly

#### Possible mutation via anytime function

```ts
const x = { a: 2 }
setTimeout(() => { Math.sin(x.a) })
x.a = "hi"
```

- Cannot assign. Restricted to number

### Asynchronous functions and promises

> TODO Promise properties
#### Async function

```ts
async function x() {
return 2
}

x satisfies string;
```

- Expected string, found Promise { 2 }

#### Await promise

```ts
async function x() {
return 2
}

(await x) satisfies string;
```

- Expected string, found 2

#### External promise

```ts
declare let a: Promise<string>;

(await a) satisfies number
```

- Expected number, found string

### Extras

This contains new features (which don't have)

#### Comments as type annotations

```ts
function x(a: /* : string */) {
function x(a /* : string */) {
a satisfies number
}

Expand Down
Loading

0 comments on commit b6e9b80

Please sign in to comment.