Skip to content

Commit

Permalink
support functions with this parameters (#15)
Browse files Browse the repository at this point in the history
Fixes #7

Porting over mmkal/ts#252 - thank you @papb for
creating that one.
  • Loading branch information
mmkal committed Oct 23, 2022
1 parent 87cecad commit 736c2bf
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 1 deletion.
24 changes: 24 additions & 0 deletions README.md
Expand Up @@ -305,6 +305,30 @@ expectTypeOf(Date).toBeConstructibleWith()
expectTypeOf(Date).constructorParameters.toEqualTypeOf<[] | [string | number | Date]>()
```

Check function `this` parameters:

```typescript
function greet(this: {name: string}, message: string) {
return `Hello ${this.name}, here's your message: ${message}`
}

expectTypeOf(greet).thisParameter.toEqualTypeOf<{name: string}>()
```

Distinguish between functions with different `this` parameters:

```typescript
function greetFormal(this: {title: string; name: string}, message: string) {
return `Dear ${this.title} ${this.name}, here's your message: ${message}`
}

function greetCasual(this: {name: string}, message: string) {
return `Hi ${this.name}, here's your message: ${message}`
}

expectTypeOf(greetFormal).not.toEqualTypeOf(greetCasual)
```

Class instance types:

```typescript
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Expand Up @@ -42,6 +42,7 @@ export type DeepBrand<T> = IsNever<T> extends true
type: 'function'
params: DeepBrand<P>
return: DeepBrand<R>
this: DeepBrand<ThisParameterType<T>>
}
: T extends any[]
? {
Expand Down Expand Up @@ -128,6 +129,7 @@ export interface ExpectTypeOf<Actual, B extends boolean> {
parameter: <K extends keyof Params<Actual>>(number: K) => ExpectTypeOf<Params<Actual>[K], B>
parameters: ExpectTypeOf<Params<Actual>, B>
constructorParameters: ExpectTypeOf<ConstructorParams<Actual>, B>
thisParameter: ExpectTypeOf<ThisParameterType<Actual>, B>
instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf<I, B> : never
returns: Actual extends (...args: any[]) => infer R ? ExpectTypeOf<R, B> : never
resolves: Actual extends PromiseLike<infer R> ? ExpectTypeOf<R, B> : never
Expand Down Expand Up @@ -180,6 +182,7 @@ export const expectTypeOf: _ExpectTypeOf = <Actual>(_actual?: Actual): ExpectTyp
'not',
'items',
'constructorParameters',
'thisParameter',
'instance',
'guards',
'asserts',
Expand Down
20 changes: 20 additions & 0 deletions test/index.test.ts
Expand Up @@ -211,6 +211,26 @@ test('Assert on constructor parameters', () => {
expectTypeOf(Date).constructorParameters.toEqualTypeOf<[] | [string | number | Date]>()
})

test('Check function `this` parameters', () => {
function greet(this: {name: string}, message: string) {
return `Hello ${this.name}, here's your message: ${message}`
}

expectTypeOf(greet).thisParameter.toEqualTypeOf<{name: string}>()
})

test('Distinguish between functions with different `this` parameters', () => {
function greetFormal(this: {title: string; name: string}, message: string) {
return `Dear ${this.title} ${this.name}, here's your message: ${message}`
}

function greetCasual(this: {name: string}, message: string) {
return `Hi ${this.name}, here's your message: ${message}`
}

expectTypeOf(greetFormal).not.toEqualTypeOf(greetCasual)
})

test('Class instance types', () => {
expectTypeOf(Date).instance.toHaveProperty('toISOString')
})
Expand Down
3 changes: 2 additions & 1 deletion test/types.test.ts
Expand Up @@ -174,7 +174,8 @@ test('parity with IsExact from conditional-type-checks', () => {
test('Equal works with functions', () => {
expectTypeOf<a.Equal<() => void, () => string>>().toEqualTypeOf<false>()
expectTypeOf<a.Equal<() => void, (s: string) => void>>().toEqualTypeOf<false>()
expectTypeOf<a.Equal<() => () => () => void, () => () => () => string>>().toEqualTypeOf<false>()
// todo: workaround https://github.com/microsoft/TypeScript/issues/50670 - https://github.com/mmkal/expect-type/issues/5
// expectTypeOf<a.Equal<() => () => () => void, () => () => () => string>>().toEqualTypeOf<false>()
expectTypeOf<a.Equal<() => () => () => void, () => (s: string) => () => void>>().toEqualTypeOf<false>()
})

Expand Down

0 comments on commit 736c2bf

Please sign in to comment.