microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
99.35k stars 12.31k forks source link

Bash Executable Types #42212

Closed jamiebuilds closed 1 year ago

jamiebuilds commented 3 years ago

Suggestion

🔍 Search Terms

List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.

✅ Viability Checklist

My suggestion meets these guidelines:

⭐ Suggestion

A hot new way of constructing types at build time using the worlds most universally beloved language: bash.

Using the bash`...` type you can now run entire bash programs inside of TypeScript.

type FileName = bash`
  find "$PWD"
`

The bash template type constructor would create a union of every stdout line of the embedded bash program.

📃 Motivating Example

Before: Allows all sorts of strings, who knows if this will work at runtime.

async function readFile(fileName: string) {
  // ...
}

After: Only real files can be read from the file system, now you can sleep at night

type FileName = bash`
  find "$PWD"
`

async function readFile(fileName: FileName) {
  // ...
}

💻 Use Cases

DanielRosenwasser commented 3 years ago

*checks date* I think you have confused 1/4/2021 and 4/1/2021 😅

jamiebuilds commented 3 years ago

There's another use case! A whole bunch of people need to be reminded to update their copyright year strings, now they can automate that reminder with $ date

type Year = bash`
  date +"%Y"
`

type Copyright = `Copyright © ${Year} Company, Inc.`

function Footer() {
  let copyright: Copyright = "Copyright © 2020 Company, Inc." // ERROR!!!! Happy 2021!!!
  return <p>{copyright}</p>
}
jamiebuilds commented 3 years ago

People have pointed out some valid security concerns with third-party dependencies using their own bash types to steal private company code. My advice is add a new entrypoint to your program which turns networking features off, thereby thwarting any and all hacking attempts that steal data.


// safe-entry.ts
type main = bash`
  nmcli networking off
  node ./unsafe-entry.ts
  nmcli networking on
`
RyanCavanaugh commented 3 years ago

This all makes sense and has no downsides, but I'm trying to figure out why bash instead of Powershell

ghost commented 3 years ago

Why use a specific scripting language that a user may or may not have, instead of, say, TypeScript?

This could be generalized into compile-time TS execution, we already sorta have it for const enums, why not just expand it to include everything?

Otherwise, this cannot possible be available everywhere anyways, ex: https://typescriptlang.org/play couldn't execute Bash :/ And fork bombing VSC on Windows would be cool, but it can't happen in Bash.

jamiebuilds commented 3 years ago

I'm trying to figure out why bash instead of Powershell

"bash" has fewer characters than "powershell" so users will save on file storage

jamiebuilds commented 3 years ago

Why use a specific scripting language that a user may or may not have, instead of, say, TypeScript?

Users can call out to ts-node from bash. By allowing bash you're actually allowing any other language of your choice!

this cannot possible be available everywhere anyways, ex: typescriptlang.org/play couldn't execute Bash :/

To be clear, I would expect TypeScript to ship its own copy of Bash for security reasons (who knows what a bad actor may do to /bin/bash)

MartinJohns commented 3 years ago

This is somewhat related to #39385, where @RyanCavanaugh wrote:

Executing user code during compilation time is the first step toward madness; we don't implement features like this and don't intend to.

Just here the "user code" is bash, not TypeScript, and it's intended for types.

jamiebuilds commented 3 years ago

Just here the "user code" is bash

aha see, therefore it is superior

MartinJohns commented 3 years ago

I have to admit that I completely missed the joke.

RyanCavanaugh commented 3 years ago

Tagging "Out of Scope" but let's agree that tag actually means "Too powerful for mere mortals to wield" in this case

weswigham commented 3 years ago

(But to the people in this thread saying "why not define the type computation in TypeScript": I've very much toyed with the idea)

typescript-bot commented 1 year ago

This issue has been marked as "Out of Scope" and has seen no recent activity. It has been automatically closed for house-keeping purposes.