From 736c2bf9785166c63f5fec9ba5de63b11977b5a0 Mon Sep 17 00:00:00 2001 From: Misha Kaletsky <15040698+mmkal@users.noreply.github.com> Date: Sun, 23 Oct 2022 06:49:56 -0400 Subject: [PATCH] support functions with `this` parameters (#15) Fixes #7 Porting over https://github.com/mmkal/ts/pull/252 - thank you @papb for creating that one. --- README.md | 24 ++++++++++++++++++++++++ src/index.ts | 3 +++ test/index.test.ts | 20 ++++++++++++++++++++ test/types.test.ts | 3 ++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 70bcec8..1cb418e 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/index.ts b/src/index.ts index b283f44..2e4532b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -42,6 +42,7 @@ export type DeepBrand = IsNever extends true type: 'function' params: DeepBrand

return: DeepBrand + this: DeepBrand> } : T extends any[] ? { @@ -128,6 +129,7 @@ export interface ExpectTypeOf { parameter: >(number: K) => ExpectTypeOf[K], B> parameters: ExpectTypeOf, B> constructorParameters: ExpectTypeOf, B> + thisParameter: ExpectTypeOf, B> instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf : never returns: Actual extends (...args: any[]) => infer R ? ExpectTypeOf : never resolves: Actual extends PromiseLike ? ExpectTypeOf : never @@ -180,6 +182,7 @@ export const expectTypeOf: _ExpectTypeOf = (_actual?: Actual): ExpectTyp 'not', 'items', 'constructorParameters', + 'thisParameter', 'instance', 'guards', 'asserts', diff --git a/test/index.test.ts b/test/index.test.ts index 95479a9..e1c0e6f 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -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') }) diff --git a/test/types.test.ts b/test/types.test.ts index 7516858..9e69af1 100644 --- a/test/types.test.ts +++ b/test/types.test.ts @@ -174,7 +174,8 @@ test('parity with IsExact from conditional-type-checks', () => { test('Equal works with functions', () => { expectTypeOf void, () => string>>().toEqualTypeOf() expectTypeOf void, (s: string) => void>>().toEqualTypeOf() - expectTypeOf () => () => void, () => () => () => string>>().toEqualTypeOf() + // todo: workaround https://github.com/microsoft/TypeScript/issues/50670 - https://github.com/mmkal/expect-type/issues/5 + // expectTypeOf () => () => void, () => () => () => string>>().toEqualTypeOf() expectTypeOf () => () => void, () => (s: string) => () => void>>().toEqualTypeOf() })