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

bun-types: infer strict Subprocess from Bun.spawn() options #1501

Merged
merged 1 commit into from
Apr 6, 2023
Merged

bun-types: infer strict Subprocess from Bun.spawn() options #1501

merged 1 commit into from
Apr 6, 2023

Conversation

paperdave
Copy link
Member

This refactors the types around Bun.spawn to properly give strict types, easing development with TypeScript.

Before and After
image
image

This is done by changing Subprocess<IO> to Subprocess<In, Out, Err>, where those three parameters are the values passed. In my opinion this also makes that interface easier to use, since you can do

function readData(process: Subprocess<any, "pipe", any>) {
  process.stdin  // FileSink | undefined
  process.stdout // ReadableStream
  process.stdout // ReadableStream | number | undefined
}

function writeData(process: Subprocess<"pipe">) {
  process.stdin  // FileSink
  process.stdout // ReadableStream | number | undefined
  process.stdout // ReadableStream | number | undefined
}

function doSomething(process: Subprocess) {
  process.stdin  // FileSink | undefined
  process.stdout // ReadableStream | number | undefined
  process.stdout // ReadableStream | number | undefined
}

and then it only accepts the process when it was spawned with stdout: "pipe"

Transformations from the Readable and Writable (unions of allowed options) to the properties that you see on Subprocess and SubprocessSync are in the following utility types:

  • ReadableToIO
  • ReadableToSyncIO
  • WritableToIO
  • OptionsToSubprocess
  • OptionsToSyncSubprocess

These are all located in the SpawnOptions namespace.

@paperdave
Copy link
Member Author

paperdave commented Nov 13, 2022

i realized my commit introduced a lot more failing type tests, just fixed those.

i also added ts-ignore to this line to fix the test error "Export declarations are not permitted in a namespace.", considering that it works fine in the intellisense. if i shouldn't have done this i can remove that.

the remaining tsd errors are from child_process and tcp stuff.

@paperdave
Copy link
Member Author

One unideal thing ive discovered is that these two types should be the same and assign to one another, but do not:

  • Subprocess<"ignore", "ignore", "ignore">
  • Subprocess<"inherit", "inherit", "inherit">

not sure off the top of my head how that would be fixed. do we want that to be something?


another idea i had would be to add some helper types for certain types of subprocesses, which you may see where i spotted the above

type ReadableSubprocess = Subprocess<any, 'pipe', 'pipe'>;
type WritableSubprocess = Subprocess<'pipe', any, any>;
type PipeSubprocess = Subprocess<'pipe', 'pipe', 'pipe'>;
type NullSubprocess = Subprocess<'ignore' | 'inherit', 'ignore' | 'inherit', 'ignore' | 'inherit'>;

should i throw these extra types in for ease of use?

@paperdave
Copy link
Member Author

about the ignore inherit thing, one solution could be to change Subprocess to accept either a strict string like "pipe" | "fd" | "null" -> Subprocess<"null", "pipe", "pipe"> for the three ways the resulting io property can be.
other idea would be to pass those types directly like Subprocess<undefined, ReadableStream<Buffer>, ReadableStream<Buffer>>; i like the strings approach a bit more, as it's a more concise when you hover over a subprocess variable, and its much less to type.

might try that out on tuesday or wednesday when i'm free

@colinhacks
Copy link
Contributor

Gorgeous ❤️

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.

2 participants