fix(types): explicit ExpectMatcherState type, optional Expect arg (#28119)

Fixes #28035.
This commit is contained in:
Dmitry Gozman 2023-11-13 18:37:50 -08:00 committed by GitHub
parent 16aee8b5d0
commit bf4c315b09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 19 deletions

View File

@ -5236,7 +5236,7 @@ export interface ExpectMatcherUtils {
stringify(object: unknown, maxDepth?: number, maxWidth?: number): string;
}
type State = {
export type ExpectMatcherState = {
isNot: boolean;
promise: 'rejects' | 'resolves' | '';
utils: ExpectMatcherUtils;
@ -5268,7 +5268,7 @@ type MakeMatchers<R, T, ExtendedMatchers> = {
rejects: MakeMatchers<Promise<R>, any, ExtendedMatchers>;
} & IfAny<T, AllMatchers<R, T>, SpecificMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>>;
export type Expect<ExtendedMatchers> = {
export type Expect<ExtendedMatchers = {}> = {
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers<Promise<void>, T> & {
@ -5277,18 +5277,13 @@ export type Expect<ExtendedMatchers> = {
*/
not: BaseMatchers<Promise<void>, T>;
};
extend<MoreMatchers extends Record<string, (this: State, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
extend<MoreMatchers extends Record<string, (this: ExpectMatcherState, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
configure: (configuration: {
message?: string,
timeout?: number,
soft?: boolean,
}) => Expect<ExtendedMatchers>;
getState(): {
expand?: boolean;
isNot?: boolean;
promise?: string;
utils: any;
};
getState(): ExpectMatcherState;
not: Omit<AsymmetricMatchers, 'any' | 'anything'>;
} & AsymmetricMatchers;

View File

@ -713,7 +713,7 @@ test('should chain expect matchers and expose matcher utils (TSC)', async ({ run
const result = await runTSC({
'a.spec.ts': `
import { test, expect as baseExpect } from '@playwright/test';
import type { Page, Locator } from '@playwright/test';
import type { Page, Locator, ExpectMatcherState, Expect } from '@playwright/test';
function callLogText(log: string[] | undefined): string {
if (!log)
@ -721,8 +721,15 @@ test('should chain expect matchers and expose matcher utils (TSC)', async ({ run
return log.join('\\n');
}
const dummy: Expect = baseExpect;
const dummy2: Expect<{}> = baseExpect;
const expect = baseExpect.extend({
async toHaveAmount(locator: Locator, expected: string, options?: { timeout?: number }) {
// Make sure "this" is inferred as ExpectMatcherState.
const self: ExpectMatcherState = this;
const self2: ReturnType<Expect['getState']> = self;
const baseAmount = locator.locator('.base-amount');
let pass: boolean;

View File

@ -370,7 +370,7 @@ export interface ExpectMatcherUtils {
stringify(object: unknown, maxDepth?: number, maxWidth?: number): string;
}
type State = {
export type ExpectMatcherState = {
isNot: boolean;
promise: 'rejects' | 'resolves' | '';
utils: ExpectMatcherUtils;
@ -402,7 +402,7 @@ type MakeMatchers<R, T, ExtendedMatchers> = {
rejects: MakeMatchers<Promise<R>, any, ExtendedMatchers>;
} & IfAny<T, AllMatchers<R, T>, SpecificMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>>;
export type Expect<ExtendedMatchers> = {
export type Expect<ExtendedMatchers = {}> = {
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers<Promise<void>, T> & {
@ -411,18 +411,13 @@ export type Expect<ExtendedMatchers> = {
*/
not: BaseMatchers<Promise<void>, T>;
};
extend<MoreMatchers extends Record<string, (this: State, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
extend<MoreMatchers extends Record<string, (this: ExpectMatcherState, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
configure: (configuration: {
message?: string,
timeout?: number,
soft?: boolean,
}) => Expect<ExtendedMatchers>;
getState(): {
expand?: boolean;
isNot?: boolean;
promise?: string;
utils: any;
};
getState(): ExpectMatcherState;
not: Omit<AsymmetricMatchers, 'any' | 'anything'>;
} & AsymmetricMatchers;