型アサーション
CoddyのLuaジャーニー「Luau入門」セクションの一部。レッスン 74/80。
列挙型の章で一度、io.read()をDirectionとして扱うために::を使いました。このレッスンでは、これについて詳しく見ていきます。
ときには、Luauの型チェッカーよりも値についてよく分かっていることがあります。たとえば、any型の値が実際にはユーザーレコードだと分かっている場合です。型アサーション(キャストとも呼ばれます)を使うと、チェッカーに「この値をこの型として扱ってください」と伝えられます。Luauのキャスト演算子は::です。
type User = {id: number, username: string}
local raw: any = {id = 42, username = "alice_dev"}
local user = raw :: User
print(user.username) -- チェッカーはこれでフィールドを認識できますキャストによって変わるのは、型チェッカーが認識する内容だけです。実行時には何も起こりません。値が変換されることはありません。"5" :: anyは数値の5ではなく、文字列の"5"のままです(実際に変換するにはtonumberを使ってください)。また、値が検証されることもありません。間違った型をアサートしても、キャスト自体はエラーになりません。存在しないフィールドにアクセスしたときに、後でコードが正常に動作しなくなるだけです。
使う場面: 値がany(または範囲の広いユニオン型)として渡され、その形が本当に分かっている場合です。使わない場面: 理解できない型エラーを黙らせるために使うことです。型エラーはたいてい実際のバグを知らせており、キャストで消しても隠してしまうだけです。実行時に検証できる場合は、次のレッスンで扱うtypeofガードのような、実際のチェックを優先してください。
チャレンジ
簡単any型で渡されるレコードを読み取ります。
type User = {id: number, username: string, isActive: boolean}と書きます。local function describeUser(data: any): stringを記述し、local user = data :: Userで型変換して、`User {user.id}: {user.username} (Active: {user.isActive})`を返します。describeUser(rawUser2)を出力します。
Run Codeを押すと、出力にUser 15: bob_admin (Active: false)が表示されます。
自分で試してみよう
-- プログラム外部からの生データ: 型は any
local rawUser1: any = {id = 7, username = "nina_dev", isActive = true}
local rawUser2: any = {id = 15, username = "bob_admin", isActive = false}
-- 1) type User = {...}
-- 2) describeUser(data: any): string、:: を使って型キャスト
-- 3) describeUser(rawUser2) を print
Luau入門のすべてのレッスン
自分で練習してみよう: Luauオンラインコンパイラ