1. ホーム
  2. object

[解決済み] TypeScriptでオブジェクトをインターフェイスにキャストする

2022-07-02 22:08:57

質問

コード内で express のリクエスト本体から (body-parser ミドルウェアを使用して) インターフェースにキャストしようとしていますが、型安全性が実施されません。

これは私のインターフェイスです。

export interface IToDoDto {
  description: string;
  status: boolean;
};

これはキャストを行おうとしているコードです。

@Post()
addToDo(@Response() res, @Request() req) {
  const toDo: IToDoDto = <IToDoDto> req.body; // <<< cast here
  this.toDoService.addToDo(toDo);
  return res.status(HttpStatus.CREATED).end();
}

そして最後に、呼び出されるサービスメソッドです。

public addToDo(toDo: IToDoDto): void {
  toDo.id = this.idCounter;
  this.todos.push(toDo);
  this.idCounter++;
}

どんな引数でも渡すことができる インターフェイスの定義と一致しないものでも そしてこのコードはうまく動作します。 レスポンスボディからインターフェースへのキャストが不可能な場合、JavaやC#のように実行時に例外が投げられると予想されるのですが。

TypeScriptではキャストは存在せず、Type Assertionのみであると読んだことがあります。したがって、オブジェクトの型が x ということです。私は間違っていますか?型安全性を強制し、保証する正しい方法は何ですか?

どのように解決するのですか?

javascriptにはキャスティングがないので、"casting fails"を投げることができません。

タイプスクリプト はキャスティングをサポートしています。 をサポートしていますが、これはコンパイル時のみで、このようにすることができます。

const toDo = <IToDoDto> req.body;
// or
const toDo = req.body as IToDoDto;

値が有効かどうかを実行時にチェックし、有効でなければエラーを投げる、つまり

function isToDoDto(obj: any): obj is IToDoDto {
    return typeof obj.description === "string" && typeof obj.status === "boolean";
}

@Post()
addToDo(@Response() res, @Request() req) {
    if (!isToDoDto(req.body)) {
        throw new Error("invalid request");
    }

    const toDo = req.body as IToDoDto;
    this.toDoService.addToDo(toDo);
    return res.status(HttpStatus.CREATED).end();
}


編集

huyzさんが指摘されているように、型アサーションは必要ありません。 isToDoDto は型ガードなので、型アサーションは不要です。

if (!isToDoDto(req.body)) {
    throw new Error("invalid request");
}

this.toDoService.addToDo(req.body);