microsoft / microsoft/TypeScript

Strongly typed TypedArray values

オープン
#62,752 コメント 6 件 リアクション 2 件 担当者 0 名 GitHub で見る
Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

### 🔍 Search Terms

"TypedArray" "TypedArray value" "indexed value" "value type"

### ✅ Viability Checklist

- [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 isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

### ⭐ Suggestion

Enable defining the value type of TypedArrays, similarly to how an Array's value type can be defined using `T[]` or `Array`. This would probably take the form of an additional generic parameter on TypedArray types with a default of `number` applied to keep backwards compatibility.

While Arrays can be defined to use an arbitrary T as their value type, TypedArrays always use the plain `number`. This is runtime-typing-wise correct, of course, but compared to the Array-case it is possible to define an Array that at runtime contains numbers but at the type level contains a subset of numbers, eg. `1 | 2 | 4` or `number & { [BRAND]: unknown }` (note that the "runtime-typing-wise correct" type for general Arrays would be `unknown` or `any`).

TypedArrays, lacking this ability, are harder to use in a code base that wants to use strongly-typed numbers through value unions or branded types. (A further feature which is not litigated here is strongly-typed indexing; the same kind of code base would quite possibly want to define an Array or TypedArray to only be indexed by a given `number & { [BRAND]: unknown }`.)

### 📃 Motivating Example

A TypedArray is used to store unique identifiers, such as indexes (handles) to a particular global storage array.

```typescript
const GLOBAL_DATA_ARRAY: unknown[] = [];

declare const GLOBAL_DATA_HANDLE_BRAND: unique symbol;
type GlobalDataHandle = number & { [GLOBAL_DATA_HANDLE_BRAND]: unknown };

const addData = (data: unknown): GlobalDataHandle => {
const existing = GLOBAL_DATA_ARRAY.indexOf(data);
if (existing !== -1) {
return existing as GlobalDataHandle;
}
const added = GLOBAL_DATA_ARRAY.length as GlobalDataHandle;
GLOBAL_DATA_ARRAY.push(data);
return added;
};

class Foo {
// currently:
#storage: Uint8Array | Uint16Array | Uint32Array;
// in the future:
#storage: Uint8Array | Uint16Array | Uint32Array;
#storageLength: number;

pushData(data: unknown): number {
this.ensureStorage(1); // reallocate #storage if it is full
const index = this.#storageLength++;
this.#storage[index] = addData(data); // okay; GlobalDataHandle is a number.
return index;
}

getDataHandle(index: number): GlobalDataHandle {
return this.#storage[index]; // error: number is not a GlobalDataHandle.
}
}
```

If `#storage` was a plain Array, this same would work without any real issue, but if the code base wants to take advantage of the (possibly) smaller memory footprint and stronger runtime value type guarantees of TypedArrays, they must add a lot of `as GlobalDataHandle` assertions; these assertions are then effectively uncheckable and as a result leads to possibly missing some errors when refactoring.

### 💻 Use Cases

1. Strongly typing TypedArray values to eg. constrain a particular TA to contain "data handles", another to contain "relative indexes", another to contain "data bitsets", and all of these TA value types to be strongly typed so as to be unique from one another and thus not be interchangeable.
2. Currently, `TypedArray & T[]` can sometimes be used but methods on the type become basically unusable, and even the value types seem to sometimes become just plain `number`.
3. The "best" thing to do today is to wrap access to the TypedArray into helper functions that `as` assert the value type: this comes at a small runtime cost as the function does not disappear even though it is entirely trivial in effect.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

既存の TypedArray 型宣言と、ブランド付きハンドルを型付き配列に格納して取得する方法を示す動機付けの例から始めます。後方互換性のあるデフォルト値を含め、ジェネリックな値の型付けでカバーすべき範囲を定義し、そのうえで、読み取りと書き込みによって要求された値の型が維持され、出力される JavaScript が変更されないことを検証します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。