Repository: TypeScript
Issue: An alternative option to `keyofStringsOnly` that stringifies numeric properties and index signatures
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:
-->

- keyof
- keyofStringsOnly

## ✅ 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 -->

Since pattern literal types like <code lang="ts">\`${number}\`</code> are valid as of <https://github.com/microsoft/TypeScript/pull/40598>, I feel like there should be an option to make:
```ts
type ArrayLikeKeys = keyof ArrayLike<any>;
```

result in:
```ts
type ArrayLikeKeys = "length" | `${number}`;
```

The same should happen for any numeric property key:
```ts
interface Foo {
	1: "a";
	2: "b";
	3: "c";
}

// Currently is: : 1 | 2 | 3
// Should be: "1" | "2" | "3"
type KeyOfFoo = keyof Foo;

// Currently is: never
type StrictKeyOfFoo = (keyof Foo) & (string | symbol);
```

like with:
```ts
interface Foo {
	"1": "a";
	"2": "b";
	"3": "c";
}

// Is: "1" | "2" | "3"
type KeyOfFoo = keyof Foo;
```

## 📃 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?
-->

This makes `keyof` and numeric index signatures match runtime behaviour.

## 💻 Use Cases

<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
  What workarounds are you using in the meantime?
-->

Currently, it’s necessary to use the `strictKeyof` and `StrictPropertyKey` helpers:
```ts
type strictKeyof<T> = keyof T extends infer K
	? (K extends number ? `${K}` : K)
	: never;

type StrictPropertyKey = string | symbol;
```


## Relevant issues:
- <https://github.com/microsoft/TypeScript/issues/27995>
- <https://github.com/microsoft/TypeScript/pull/35594#discussion_r355727393>, <https://github.com/microsoft/TypeScript/pull/35594#discussion_r356496551>, <https://github.com/microsoft/TypeScript/pull/35594#discussion_r355728724>
- <https://github.com/microsoft/TypeScript/issues/41669>
- <https://github.com/microsoft/TypeScript/pull/41987>
- <https://github.com/microsoft/TypeScript/pull/48837>
- <https://github.com/microsoft/TypeScript/issues/48957>

---

This will most likely depend on <https://github.com/microsoft/TypeScript/pull/26797>, so that treating numeric index signatures as numeric pattern literal index signatures is valid:
```ts
interface ArrayLike<T> {
	readonly [index: `${number}`]: T;
	readonly length: number;
}
```