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

Moved repo to strict: true and restructured tsconfig.jsons to use project references #567

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

mattpocock
Copy link
Contributor

@mattpocock mattpocock commented Aug 20, 2024

No changeset needed, not a user-facing change.

Copy link

changeset-bot bot commented Aug 20, 2024

⚠️ No Changeset found

Latest commit: 276b3b6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

"lint": "eslint ./src --ext .ts",
"format": "prettier --write 'src/**/*.ts?(x)' && npm run lint -- --fix",
"typecheck": "tsc --noEmit",
"typecheck": "tsc -b",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now, this typecheck command checks the entire repo, including the typecheck tests.

Copy link
Owner

Choose a reason for hiding this comment

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

Doesn't this create artifacts, though? Shouldn't it be tsc -b --noEmit?

The whole intention of the typecheck script is to typecheck without generating artifacts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, noEmit has been moved to the config file - this is so that users running tsc without using the command don't accidentally generate artifacts.

@@ -969,9 +962,9 @@ describe('ResultAsync', () => {
it('Accepts an error handler as a second argument', async () => {
const example = ResultAsync.fromThrowable(
() => Promise.reject('No!'),
(e) => new Error('Oops: ' + e)
(e) => new Error('Oops: ' + e),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like prettier changes in this file.

"exclude": [],
"references": [
{
"path": "./tsconfig.tests.json"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is now referenced in the root tsconfig, meaning both can be run simultaneously.

@mattpocock mattpocock changed the title Upgraded TS and moved to strict: true Moved repo to strict: true and restructured tsconfig.jsons to use project references Aug 20, 2024
"declaration": true,
"baseUrl": "./src",
"lib": [
"dom",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the DOM types, not needed here.

"sourceMap": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Slimmed down the tsconfig by flags inferred by other flags.

@mattpocock mattpocock marked this pull request as draft August 20, 2024 08:31
@mattpocock mattpocock mentioned this pull request Aug 20, 2024
10 tasks
Copy link
Owner

Choose a reason for hiding this comment

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

I don't think neverthrow should include editor specific files. Please remove.

Comment on lines +26 to +35
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return ((...args: any[]) => {
try {
const result = fn(...args)
return ok(result)
} catch (e) {
return err(errorFn ? errorFn(e) : e)
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}) as any
Copy link
Owner

Choose a reason for hiding this comment

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

Can you explain the rationale for these as any changes made here and in other files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moving to strict: true revealed some errors that I didn't have time to debug. I suggest we 'as any' them now, and fix them in a followup PR.

Copy link

@boyeln boyeln Sep 11, 2024

Choose a reason for hiding this comment

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

The reason this errors and you have to as any it is because with this call signature you can in theory do something like:

const safeParse = fromThrowable<typeof JSON.parse, number>(JSON.parse);
      // ^ (text: string, reviver?: (this: any, key: string, value: any) => any) => Result<any, number>

So by allowing providing a specific generic type as E without providing an errorFn, you can get in trouble. You can then end up in a case where you try to pass e to the err in the catch block (in the second/false ternary case), but since the user might have specified a specific E (like number in the example above), you can't just give it the unknown (or any here I suppose)e.

The easiest fix might be to add some overloads to prevent using the function as I did above:

export function fromThrowable<Fn extends (...args: readonly any[]) => any>(
  fn: Fn
): (...args: Parameters<Fn>) => Result<ReturnType<Fn>, unknown>;
export function fromThrowable<Fn extends (...args: readonly any[]) => any, E>(
    fn: Fn,
    errorFn: (e: unknown) => E,
  ): (...args: Parameters<Fn>) => Result<ReturnType<Fn>, E>;
  export function fromThrowable<Fn extends (...args: readonly any[]) => any, E>(
    fn: Fn,
    errorFn?: (e: unknown) => E,
  ): (...args: Parameters<Fn>) => Result<ReturnType<Fn>, E | unknown> {
    // implementation
}

I don't know if it really makes any practical difference here, but I believe it would be more correct to do catch (e: unknown) to have e typed as unknown and not the default any.

This could of course happen in a different PR. And I suppose in theory changing the call signature as I proposed might be considered a breaking change. However, if someone is using the function as I did above they should stop doing as it probably gives you types that don't match the runtime types. So you could consider it a bug maybe 🤷

Copy link

Choose a reason for hiding this comment

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

I created a separate PR for fixing the issue: #583 However, feel free to close that PR and include the changes here instead if that's better.

"lint": "eslint ./src --ext .ts",
"format": "prettier --write 'src/**/*.ts?(x)' && npm run lint -- --fix",
"typecheck": "tsc --noEmit",
"typecheck": "tsc -b",
Copy link
Owner

Choose a reason for hiding this comment

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

Doesn't this create artifacts, though? Shouldn't it be tsc -b --noEmit?

The whole intention of the typecheck script is to typecheck without generating artifacts.

"declaration": true,
"composite": true,
"outDir": "./tests/dist",
"noEmit": false
Copy link
Owner

Choose a reason for hiding this comment

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

Shouldn't this be "noEmit": true?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using project references means that you do need to generate declaration files. This acts as a kind of cache for TS, making things run a bit faster.

These files are outputted to ./tests/dist, as specified in outDir

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.

3 participants