web-dev-qa-db-ja.com

TypeScriptは不変/ const / readonly配列を返します

配列を返す関数が必要ですが、返された配列を読み取り専用にしたいので、内容を変更しようとすると警告/エラーが表示されます。

function getList(): readonly number[] {
   return [1,2,3];
}


const list = getList();
list[2] = 5; // This should result in a compile error, the returned list should never be changed

TypeScriptでこれを実現できますか?

14
XCS

これはうまくいくようです...

function getList(): ReadonlyArray<number> {
    return [1, 2, 3];
}

const list = getList();

list[0] = 3; // Index signature in type 'ReadonlyArray<number>' only permits reading.

Playground でお試しください

ReadonlyArray<T>は次のように実装されています:

interface ReadonlyArray<T> {
    readonly [n: number]: T;
    // Rest of the interface removed for brevity.
}
10
Matthew Layton

TypeScript 3.4がReadonlyArray の新しい構文を導入して以来、OPからのコードそのものが機能するようになりました。

ミューテーションを意図しない場合は、ReadonlyArrayArrayよりも使用することをお勧めしますが、配列の構文が優れていることを考えると、多くの場合面倒です。具体的には、number[]Array<number>の省略形であるのと同様に、Date[]Array<Date>の省略形です。

TypeScript 3.4では、配列型に新しいReadonlyArray修飾子を使用するreadonlyの新しい構文が導入されています。

このコードは期待どおりに動作します。

function getList(): readonly number[] {
   return [1,2,3];
}

const list = getList();
list[2] = 5; // <-- error

遊び場

4
Borek Bernard

以下はリストを読み取り専用にしますが、その中のアイテムはできません:

function getList(): Readonly<number[]> {
   return [1,2,3];
}

let list = getList();
list = 10; // error
list[1] = 5 // that is fine

そして、これはリストとそのアイテムを読み取り専用にします:

function getList(): ReadonlyArray<number> {
   return [1,2,3];
}

let list = getList();
list = 10; // error
list[1] = 5 // error as well
3
Avraam Mavridis

TypeScriptには ReadonlyArray<T> これを行うタイプ:

TypeScriptには、すべての変更メソッドが削除されたArrayと同じReadonlyArray型が付属しているため、作成後に配列を変更しないようにすることができます

function getList(): ReadonlyArray<number> {
   return [1,2,3];
}

const list = getList();
list[2] = 5; // error

for (const n of list) {
    console.log(n);
}
1
millimoose