Repository: TypeScript
Issue: [Suggestion] a "const mode" where `as const` is by default for literals
Labels: Suggestion,Awaiting More Feedback

# Suggestion

<!--
  Please fill in each section completely. Thank you!
-->

## 🔍 Search Terms

<!--
  💡 Did you know? TypeScript has over 2,000 open suggestions!
  🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
  The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests

  Replace the text below:
-->

const by default, const mode, use const, as const

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

<!-- A summary of what you'd like to see added or changed -->
An optional `const mode`, manually enabled by `tsconfig` or  cli options or maybe a `"use const"` directive.
In const mode, a selective subset of js literals (like all primitive literals, and usually arrays) are `as const` by default, eg.
```ts
'use const'
const bool = true // typeof bool is `true` instead of `boolean`
const foo = 'foo' // typeof foo is `foo` instead of `string`
const num = 0 // 0, instead of `number`
const tuple = [ 'foo', true ] // typeof tuple is readonly [ 'foo', true ]
const record = { 'foo': 'bar', 'bar': 0 } // typeof record is { 'foo': 'bar', 'bar': 0 }
```
or some alternative directives:
```ts
'use const string'
'use const primitive'
'use const Array'
'use const Object'
```
When the non-const type is wanted:
```ts
'use const'
let bool = true // suggested optionally: const mode can be disabled for `let`.
const arr: string[] = [ 'foo', 'bar' ] // manually declare the type
```

## 📃 Motivating Example

<!--
  If you were announcing this feature in a blog post, what's a short explanation that shows
  a developer why this feature improves the language?
-->
Literals, esp. primitive literals assigning to constant variables usually have a good chance to remain what they are during their whole lifetime. Applying `as const` by default can further improve type safety and convenience in projects where type safety is valued.

## 💻 Use Cases

<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
  What workarounds are you using in the meantime?
-->
Literally to type less `as const`.