Skip to content

feat: add types#44

Closed
isaacs wants to merge 3 commits intonpm:mainfrom
isaacs:main
Closed

feat: add types#44
isaacs wants to merge 3 commits intonpm:mainfrom
isaacs:main

Conversation

@isaacs
Copy link
Copy Markdown
Contributor

@isaacs isaacs commented Jan 20, 2023

Make editors and typescript happy!

The @types/read package is not up to date with the async/await interface changes, and it's often convenient to just have these things local in the module anyway.

References

@isaacs isaacs requested a review from a team as a code owner January 20, 2023 06:22
lib/read.d.ts Outdated
/// <reference types="node" />
import type { ReadLineOptions } from 'node:readline'

declare function Read<T = string>(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It might be safer to just always use string instead of inferring an alternate type from the default option, but I figured this was the least obtrusive way to do it. So if you do const x = await read({ def: 1 }) then x will be string | number. Since the default option isn't forced to be a string in the code, this seems safest, and shouldn't complain if anyone is using it that way today.

@lukekarrys
Copy link
Copy Markdown
Contributor

lukekarrys commented Jan 20, 2023

what's the best way to assert these types remain correct in CI? will tsc validate these against the JS file?

The @types/read package is not up to date with the async/await interface
changes, and it's often convenient to just have these things local in
the module anyway.
@isaacs
Copy link
Copy Markdown
Contributor Author

isaacs commented Mar 21, 2023

what's the best way to assert these types remain correct in CI? will tsc validate these against the JS file?

Well, one easy way is to write the module in TS. I'd be happy to send a PR to do that like the other modules I've been updating, exporting a CJS and MJS version so it all Just Works. But of course, that's a bigger patch.

The other way is to write tests in TS, so that any mis-typings cause test failures.

The best is to do both, of course.

But other than that, no, there's really no reliable way to ensure that the JS and types match, without actually running code in a way that it's forced to compile and check against the actual thing.

import { spawn } from 'child_process'

const esc = (str: string) =>
str.replace(/\(/g, '\\(').replace(/\)/g, '\\)')

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding

This does not escape backslash characters in the input.
import { spawn } from 'child_process'

const esc = (str: string) =>
str.replace(/\(/g, '\\(').replace(/\)/g, '\\)')

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding

This does not escape backslash characters in the input.
@isaacs
Copy link
Copy Markdown
Contributor Author

isaacs commented Mar 21, 2023

Updated the PR with two more commits to do those two things. Take both or neither, as you like :)

This is the pattern I've been using to ship modules that work in esm or commonjs mode transparently, with types guaranteed to be in sync with the code, etc. It's a mild bummer having to resort to c8 for coverage, since you lose the --check-coverage and other fancy tap features, but until I can finish tap 18, that's the best available.

@wraithgar
Copy link
Copy Markdown
Member

I think this is a little more than we're ready to take on at this time.

@wraithgar wraithgar closed this Apr 12, 2023
@lukekarrys lukekarrys reopened this Oct 31, 2023
@lukekarrys lukekarrys closed this Oct 31, 2023
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