-
-
Notifications
You must be signed in to change notification settings - Fork 698
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
base: main
Are you sure you want to change the base?
Conversation
"pathval": "^2.0.0", | ||
"@types/check-error": "^1.0.3", | ||
"@types/deep-eql": "^4.0.2", | ||
"@types/pathval": "^1.1.2" |
There was a problem hiding this comment.
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
src/chai/assertion.ts
Outdated
[k in keyof T]: T[k] extends (...args: never) => void ? k : never; | ||
}[keyof T]; | ||
|
||
const getDefaultValue = (assertion: Assertion): Assertion => { |
There was a problem hiding this comment.
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
src/chai/assertion.ts
Outdated
util.flag(this, 'eql', config.deepEqual ?? util.eql); | ||
} | ||
|
||
public static create( |
There was a problem hiding this comment.
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
I'm gonna convert this to a draft while it's a WIP. Hope that's OK :) |
@@ -0,0 +1,19 @@ | |||
{ | |||
"compilerOptions": { | |||
"target": "es2021", |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
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:
|
I've browsed the code base quite a bit and I think there is some work to be done after migrating to TypeScript. 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'. ;) |
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.
FYI i've caught this up and manually diffed against the current JS sources (since git won't do that for everything in this case) everything seems fine so I think we should just ship a I considered the prev comment too but doing a typescript conversion a step at a time will be pretty difficult since everything is so intermingled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! I'm excited about having types, even if we can refine the types in the future I'm happy to start with something like this and then add more type coverage as we go along.
Maybe we can create a next
branch which will automatically publish to the next
tag on npm
and we can see if we can work together to make small PRs towards that branch until we're satisfied with the functionality and type-coverage. At that point we can make a PR main
and get that published as chai@6.
Only change I would like to make before continuing is to make sure that files we are renaming/moving retains their history and don't show up as deleted and recreated. Currently in this PR the files lib/chai/assertion.js
, lib/chai/interface/expect.js
and lib/chai/utils/flag.js
are deleted when they should be moved so that they retain the history.
@@ -29,14 +34,15 @@ | |||
"main": "./chai.js", | |||
"scripts": { | |||
"prebuild": "npm run clean", | |||
"build": "npm run build:esm", | |||
"build:esm": "esbuild --bundle --format=esm --keep-names --outfile=chai.js index.js", | |||
"build": "npm run build:ts && npm run build:esm", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we doing both? Is it to check for type errors? If yes, can we create a "lint:types": "tsc --noEmit"
task and run that in the existing lint
task?
@@ -56,6 +65,7 @@ | |||
"esbuild": "^0.19.10", | |||
"eslint": "^8.56.0", | |||
"eslint-plugin-jsdoc": "^48.0.4", | |||
"mocha": "^10.2.0" | |||
"mocha": "^10.2.0", | |||
"typescript": "^5.3.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about changing this to a tilde since TypeScript doesn't follow semver?
"typescript": "^5.3.3" | |
"typescript": "~5.3.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to a rename/move so that we keep the git history of this file intact?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they're all renames, git just can't figure it out. don't think there's much we can do here
locally, I've been using git diff main:foo.js foo.ts
or something like that
afaik git determines if its a move at the time of diff, not in commit metadata. so its probably just too big of a change for it to infer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you move the files with git mv
or just move them normally? If I recall git mv
will do the right thing but moving normally, git can't recognize if the file is moved or not if the delta between the changes is high enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved them with git mv
Sometimes git just doesn't manage to keep track of them. I've seen this many times in big refactors but not sure why
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird! But yeah no worries then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to a rename/move so that we keep the git history of this file intact?
/*! | ||
* Module dependencies | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/*!
comments are generally considered "legal comments" and will not be removed by bundlers. Probably users will not be bundling this but I still think this could be a normal comment.
/*! | |
* Module dependencies | |
*/ | |
/** | |
* Module dependencies | |
*/ |
I'm also thinking we could just remove it as it's clear that these are dependencies.
/*! | |
* Module dependencies | |
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to a rename/move so that we keep the git history of this file intact?
(Also sorry for the really late review, I've been moving countries and I haven't been checking my notifications enough. Always feel free to ping (and re-ping) me for reviews <3) |
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
$ExpectType
tests (there's an eslint plugin for this now)Some of these should probably be in their own PR.
For reviewers
Some things to review thoroughly:
files
in the package manifest