Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assert type problems: can't extend assertion types in TypeScript #128

Closed
mindplay-dk opened this issue Dec 16, 2021 · 0 comments · Fixed by #129
Closed

Assert type problems: can't extend assertion types in TypeScript #128

mindplay-dk opened this issue Dec 16, 2021 · 0 comments · Fixed by #129

Comments

@mindplay-dk
Copy link
Contributor

It looks like there's a problem, possibly with the compiled .d.ts file.

In my test-harness I'm trying to add a custom assertion:

import { Assert, IAssert } from "zora";

declare module "zora" {
  interface IAssert {
    valid: typeof valid;
  }
}

const valid = <T>(
  actual: T,
  check: (value: T) => boolean,
  description = 'check should return true'
) => {
  const pass = check(actual);
  const expected = check.toString();

  return {
    pass,
    actual,
    expected,
    description,
    operator: "equal",
  };
};

Assert.valid = valid; // 👈 error

Looking at the declaration of Assert, it's declare const Assert: IAssert$1 - where IAssert$1 apparently is/was the types imported here:

import { IAssert as GenericAssertionAPI } from '../../../assert/src/index';

That type contains the built-in standard assertions:

export interface IAssert {
equal: ComparatorAssertionFunction;
equals: ComparatorAssertionFunction;

So there are two different IAssert, and that's probably why the compiler renames one to IAssert$1, which isn't exported.

The IAssert that gets renamed to IAssert$1 is the one used to type-hint the built-in standard assertions:

export declare const Assert: IAssert;

But that's not the type that gets exported:

export interface IAssert extends GenericAssertionAPI, ITester {}

So the IAssert that gets exported isn't the type of Assert.

I can only reach and extend the IAssert type, which doesn't affect the IAssert$1 type, which means there's no (valid, type-safe) way to actually inject anything into Assert.

I've attempted to inject custom assertions before and always assumed it was me doing something wrong, but I'm pretty sure something isn't right with this type relationship - it appears to be backwards? Or something.

I can get around it for now with (Assert as any).valid = valid - it works, but it doesn't type-check.

I think, since the exported IAssert inherits from the internal IAssert, the internal one would need to be exported as well?

It might be a good idea to rename one of the IAssert types to clarify the fact that one defines the available assertions, while the other defines the combined API with Tester members that gets provided to the tests?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant