Helpfeelエンジニアの id:nedew です。
関西の TypeScript 関係者が集う一大イベント TSKaigi Kansai 2024 が11月16日に京都で開催され、弊社HelpfeelもGold Sponsorとして参加しました。
弊社ブースでは恒例のガチャガチャやステッカーなどの配布に加え、今回の TSKaigi Kansai 2024 用に制作した TypeScript の試験問題を配布を行い、たくさんの方々に解答していただきました!
今回はそんなTypeScript試験「型情報 I」の問題および解答を公開します。
実際に会場で配布した問題と回答用紙のデータも公開しておりますので、より試験っぽい雰囲気を味わいたい方は以下からご覧ください!
問題解説
問1
以下の TypeScript に関する問題に答えなさい。 (配点 50)
〔1〕 TypeScript のunknown
型について、正しい説明を選びなさい。
A. unknown 型は any 型と同じで、どんな操作でも型エラーにならない。 B. unknown 型の変数を利⽤する際には、事前にその型を判別するための型の絞り込みが必須である。 C. unknown 型は他の型に直接代⼊できる。 D. unknown 型の利⽤は strict モードでは許可されない。
解答と解説を見る
unknown
型 は TypeScript 3.0 で導入された型で、any
型に似て「どんな型でも代入できる」という特徴がありますが、unknown
型をそのまま利用することはできません。
unknown
型の変数を利用する場合、まずは「その変数がどの型に該当するか」を判別し、適切な型の絞り込みを行う必要があります。const value: unknown = "Hello, TypeScript!";
// value が文字列型か確認
if (typeof value === "string") {
// このブロック内において value は string 型の変数として扱えます
const message: string = value
}
unknown
型は any
型とは異なり、直接的な操作を行うと型エラーが発生するため、any
型のようにどんな操作も許容されるわけではありません。unknown
型は他の型に直接代入できません。型の絞り込みやキャストを行う必要があります。unknown
型は strict モードでも利用可能で、むしろ strict な型付けに役立つツールとして使われます。
〔2〕 NonNullable<Type>
によって取り除かれる型をすべて選びなさい。
A. null B. undefined C. void D. never
TypeScript のユーティリティ型 解答と解説を見る
NonNullable<T>
は、ユニオン型から null および undefined を取り除く型を返しますtype Example = NonNullable<string | null | undefined>; // 結果: string
void
は関数が値を返さないことを示す型で、NonNullable<T>
によって取り除かれませんnever
は「値を持たない」を示す型で、こちらもNonNullable<T>
によって取り除かれません
〔3〕 次の条件型はどの型と等しくなりますか。
type Result = 1 extends number ? "Yes" : "No";
A. 1 B. number C. "Yes" D. "No"
この問題では、条件型を利用した型の評価について問われています。 TypeScript の条件型は以下の形式で記述されます。 これは A が B に代入可能であれば X になり、そうでない場合は Y になります。 これらを踏まえて問題を見返すと、解答と解説を見る
A extends B ? X : Y
number
型は1
というリテラル型を内包する super type であり、1
はnumber
型に代入可能なため、true branch側の"Yes"
が正解です。
〔4〕 次のResult
型に⼀致する型を選びなさい。
type MysteryType<T> = T extends Array<infer U> ? U : T; type Result = MysteryType<string[]>;
A. string B. string[] C. boolean D. never
この問題では、条件型(Conditional Types)と 解答と解説を見る
infer
を利用した型推論の仕組みについて問われています。
T extends Array<infer U> ? U : T
は T
が配列型に代入可能であれば U
を返し、そうでなければ T
を返します。infer U
は型推論を行うキーワードで、T
が配列型の場合、その配列の要素型を推論して U
に割り当てますstring[]
が渡されているため、T
は string
型 の配列であり、U
は string
型であると推論されます
number[]
を渡した場合は U
は number
となる)T
がstring[]
のときT extends Array<infer U>
の左辺は右辺に代入可能となり、string
と推論された U
が返るため、正解はAの string
です
〔5〕 以下の単語について、TypeScript 5.6 までにキーワードとして解釈できるようになった順に正し く並べられたものをひとつ選びなさい。
A. readonly -> protected -> using -> satisfies B. satisfies -> using -> protected -> readonly C. using -> readonly -> satisfies -> protected D. protected -> readonly -> satisfies -> using
それぞれ下記のバージョンにてキーワードとして解釈可能になりました。解答と解説を見る
問2
Products
型には、株式会社 Helpfeel のプロダクト名が列挙され、各プロダクトの提供状況が⽂字列で記載されています。
この中から「提供中」のプロダクト名だけを抽出し、ユニオン型として表現するAvailableProductName
型を完成させてください。 (配点 20)
type Products = { Gyazo: '提供中'; Helpfeel: '提供中'; Scrapbox: 'ScrapboxはCosenseに名前が変わりました'; Cosense: '提供中'; }; // AvailableProductNameが "Gyazo" | "Helpfeel" | "Cosense" になるように完成させてください type AvailableProductName = { [K in keyof Products]: Products[K] extends '提供中' ? 【解答】 : never }[keyof Products];
A. string B. K C. Products D. Products[K]
Mapped Typesへの理解と、neverを用いたユニオン型のフィルタリング知識を問う問題です。 解答と解説を見る
[K in keyof Products]
によって、Products
型のすべてのキー("Gyazo" | "Helpfeel" | "Scrapbox" | "Cosense"
)が K
に渡されますK
を当てはめて Products[K] extends '提供中' ? K : never
とします
K
に対応する値 Products[K]
を条件型で評価します'提供中'
であればキー K
を結果に含め、それ以外の場合は never
を返します{
Gyazo: "Gyazo";
Helpfeel: "Helpfeel";
Scrapbox: never;
Cosense: "Cosense";
}
[keyof Products]
を用いて全ての値の型を抽出しますnever
はユニオン型から除外されるため、最終的に以下の期待する型が得られます"Gyazo" | "Helpfeel" | "Cosense"
問3
株式会社 Helpfeel は 3 つのプロダクトを展開しています。それぞれのアイコンを答えなさい。(配点 20)
- Gyazo
- Cosense
- Helpfeel
① 1 ‒ A、2 ‒ C、3 ‒ B ② 1 ‒ C、2 ‒ B、3 ‒ A ③ 1 ‒ B、2 ‒ A、3 ‒ C
よく見るとそれぞれプロダクト名の頭文字を反映させたロゴになっています。解答と解説を見る
ブースで配布していたチラシやパンフレットにもヒントがあったようです。
問4
次のコードを実⾏したとき、コンソールに出⼒される⽂字列はどれですか。 (配点 10)
function getRecruitmentMessage(): string { if ("true" === "true") { return "Helpfeel社はエンジニア、マネージャーなど幅広く大募集中!あなたの出番です!"; } else { return "Helpfeel社は現在募集を行っておりません"; } } console.log(getRecruitmentMessage());
①Helpfeel社はエンジニア、マネージャーなど幅広く大募集中!あなたの出番です! ②Helpfeel社は現在募集を行っておりません
解答と解説を見る
まとめ
皆さんは何点でしたか?
こういった試験問題の配布は初の試みだったのでうまくいくか不安でしたが、予想以上に多くの方に解答していただき、また楽しんでいただけたのかなという感触があり、やってよかったなという気持ちです。
一方で問題の難易度や採点フローなど課題も見えたので、また機会があればリベンジさせてください。
改めてブースに足を運んでいただいた皆さん本当にありがとうございました。
次回の undefined 試験でお会いしましょう。