unknown型ってなに?
簡単に言うと制約の強いany型です。
any型のように何でも代入できます。
let a: unknown;
a = 0; // OK
a = "あいうえお"; // OK
a= { key: "オブジェクト" }; // OK
しかしany型とは違いそのままでは型が明示された他変数への代入やメソッド呼び出しができません。
また型アサーションで型推論を上書きすることもできません。
const a: unknown = "abc";
// Type 'unknown' is not assignable to type 'string'.でエラーになる
const b: string = a;
// 'a' is of type 'unknown'.でエラーになる
a.toUpperCase();
a as string;
// 'a' is of type 'unknown'.で型アサーションでstringとして型推論を上書きできない
a.toUpperCase();
型が明示された他変数への代入やメソッド呼び出し方法
型を絞り込むと代入できるようになります。
const a: unknown = "abc";
if (typeof a === "string") {
// 型を絞り込んだif内ではstring型として扱えるようになる。
const b: string = a;
a.toUpperCase();
}
// プロパティも同じようにできる
type E = {
name: unknown;
};
const e: E = {name: ""};
if (typeof e.name === "string") {
const b: string = e.name;
e.name.toUpperCase();
}
// 連想配列も同じようにできる
const d: Record<string, unknown> = {"test": "test"};
const test = "test";
if (typeof d[test] === "string") {
const b: string = d[test];
d[test].toUpperCase();
}
しかし配列は型を絞り込む前にisArrayで配列であるか確認しないといけません。
const c: [unknown] = [""];
if (Array.isArray(c) && typeof c[0] === "string") {
const b: string = c[0];
c[0].toUpperCase();
}
また連想配列は変数でKeyを指定して型や引数を絞り込むことができません。
(定数は絞り込みできます。)
const d: Record<string, unknown> = {"test": "test"};
let test = "test";
if (typeof d[test] === "string") {
// Type 'unknown' is not assignable to type 'string'.
const b: string = d[test];
// Object is of type 'unknown'.
d[test].toUpperCase();
}
any型との違いをまとめ
any型 | unknown型 | |
---|---|---|
代入できる値 | なんでもOK | なんでもOK |
他変数への代入 | できる | 型を絞り込まないといけない |
アサーションによる型推論を上書き | できる | 型を絞り込まないといけない |
メソッドやプロパティの呼び出し | 存在したら呼び出せる | 存在しても型を絞り込まないといけない |
尾張!平定!…以上!皆解散!