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

feat: migrate to typescript #1567

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft

feat: migrate to typescript #1567

wants to merge 11 commits into from

Conversation

43081j
Copy link
Contributor

@43081j 43081j commented Dec 30, 2023

This is an initial attempt at migrating the codebase to typescript.

The tests and build should pass but we can go further and do more with the types.

WIP until we do that.

cc @keithamus @koddsson

TODO

  • strengthen a lot of the types with inference etc
  • remove as many casts as possible
  • add some $ExpectType tests (there's an eslint plugin for this now)
  • run a formatter
  • add a linter

Some of these should probably be in their own PR.

For reviewers

Some things to review thoroughly:

  • the various overloads of assertion functions
    • we do a lot of overloading which is super awkward in a strongly typed world, so these need a very close look
  • the addition of files in the package manifest
    • make sure we pack the right files

"pathval": "^2.0.0",
"@types/check-error": "^1.0.3",
"@types/deep-eql": "^4.0.2",
"@types/pathval": "^1.1.2"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you're curious: these are prod dependencies since we export some of them in our public interface. so typescript consumers need to pull these types down too

[k in keyof T]: T[k] extends (...args: never) => void ? k : never;
}[keyof T];

const getDefaultValue = (assertion: Assertion): Assertion => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without this, we end up with circular imports: assertion.js -> addMethod.js -> assertion.js.

it is probably a bad idea to have such a circular dependency, so i extracted it into a factory function we now have to pass in (if we want an assertion to be the return value).

if anyone has a better idea, i'm all ears

util.flag(this, 'eql', config.deepEqual ?? util.eql);
}

public static create(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can't really proxify ourselves, so i've introduced this new factory method.

you should call this near enough everywhere, instead of new Assertion

@koddsson
Copy link
Member

koddsson commented Jan 5, 2024

WIP until we do that.

I'm gonna convert this to a draft while it's a WIP. Hope that's OK :)

@koddsson koddsson marked this pull request as draft January 5, 2024 13:10
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es2021",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should figure out our support matrix and set this accordingly. Currently I'm not sure why we wouldn't change this to esnext or es2024.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, i just chose it arbitrarily. i wasn't sure if esnext would be too loose and we should tie into a particular revision

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can set up a browserlists config to make sure we are adhering to whatever support matrix we decide.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SmashingQuasar
Copy link

Hey @43081j !

I love Chai and I have been using it for years. This PR is extremely interesting and migrating to TypeScript would do a world of good to this library.
If you want, I'm ready to help you with this so we can lift Chai to the next level. Just let me know so we can sync' on this and work together to finish it up. :)

@43081j
Copy link
Contributor Author

43081j commented Feb 26, 2024

before we can really split the work up to contributors etc, i think i really need a thorough review from @koddsson or @keithamus to make sure we're on the right track and in agreement

there's a couple of awkward patterns lying around that i want to clean up before this can ever land:

  • passing a createDefaultValue around feels awkward, but its better than a circular import. i feel like there must be a third solution though with a bit of a refactor
  • logic has changed in some places, usually in functions with overloads. not sure how we want to deal with that in terms of semver
  • there's a bunch of casts i think we can get rid of with some thought

@SmashingQuasar
Copy link

I've browsed the code base quite a bit and I think there is some work to be done after migrating to TypeScript.
There are some code sections that look really difficult to understand and maintain. Especially those functions created within functions. There are also some wild var at different places and other things that look like they could be improved.

It's most likely an heirloom of some older sections of the code base which is to be expected. All of this to say that it would be easier to have a first base that is using TypeScript, event approximately, and then refactor fractions of the code base in different PRs.

My point is: I don't think it's too big of a deal if you have some things that aren't totally perfect, we can work on this afterwards. :)

I'm not a maintainer, not even a contributor yet, so it's just the opinion of one random dev'. ;)

43081j added 11 commits May 4, 2024 18:24
This is an initial attempt at migrating the codebase to typescript.

The tests and build should pass but we can go further and do more with
the types.

WIP until we do that.
This way, we can hold them in a non-generic array without the need for
`any`. Later, when we need to call the method, we will have to cast it
to a callable signature.
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 this pull request may close these issues.

None yet

3 participants