質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

NextJs13 + TypeScript + Socket.io でのWebSocket通信でレスポンスの型がわからない。

katatema01
katatema01

総合スコア23

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

2回答

0グッド

0クリップ

231閲覧

投稿2022/11/13 03:51

前提

NextJs13 +TypeScript + Socket.io でWebSocket通信を試しています。
以下のURLを参考に実装~動作確認まで行うことができたのですが、
https://blog.logrocket.com/implementing-websocket-communication-next-js/

socketHandlerの引数にしているresの型がわからず、仕方なくanyにしています。

TypeScript

1import type { NextApiRequest } from 'next' 2import { Server } from 'Socket.IO' 3 4export default function socketHandler(req: NextApiRequest, res: any) { 5 if (res.socket.server.io) { 6 console.log('Socket is already running') 7 } else { 8 console.log('Socket is initializing') 9 const io = new Server(res.socket.server) 10 res.socket.server.io = io 11 12 io.on('connection', (socket) => { 13 socket.on('input-change', (msg) => { 14 socket.broadcast.emit('update-input', msg) 15 }) 16 }) 17 } 18 res.end() 19}

実現したいこと

anyにせず正しい型を指定することは可能でしょうか?
また、TypeScriptを触り始めたのですが、nodejsのライブラリなどを使用していると、
ライブラリで扱っている型がわからず、
「とりあえず、anyにして回避する。」というケースが、
結構、発生しています。
何か調べ方などは、あるのでしょうか?

試したこと

試しに、
res: any を res: NextApiResponse に変更してみたところ
VS-Code上で
「プロパティ 'server' は型 'Socket' に存在しません。ts(2339)」
と表示されました。

ただ、npm run dev して、動作を確認してみても特に問題なく動作している様に見えるので、
VS-Code上だけの問題?なのかとも思います。
どちらにせよ、エラー表示のまま使用したり、「とりあえずany」は、
ダメな手法な気がしますので、なんとかならないものか?と思っています。

補足情報(FW/ツールのバージョンなど)

nodejs v16.18.0
nodejsパッケージは以下
"next": "13.0.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"socket.io": "^4.5.3",
"socket.io-client": "^4.5.3",
"typescript": "4.8.4"

windows11 のVS-Code上で試しています。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答2

1

javascript - Working with TypeScript, Next.js, and Socket.io - Stack Overflow が参考になるかと思います。ちなみにこのページは「Socket.IO res typescript nextjs」で検索してヒットしました。

NextApiResponseという型情報は、Socket.IOのレスポンスの型情報を含まないため、自分で拡張してあげる必要がありそうです。


「試したこと」にあるように、anyにしたとしてもTypeScriptの型情報はランタイムには直接影響はしないため、動作上は一見問題ないように見えます。しかし、anyを使っていると本来の型情報とは異なるプロパティを参照するなどした際にエラーになるため、あまり安全とは言えません。可能であれば、何かしらの教材でTypeScriptの型システムについてもう少し学習してみることをオススメします。

投稿2022/12/06 06:03

y-temp4

総合スコア23

katatema01👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

katatema01

2022/12/06 07:57

解決の一助となりました。 ありがとうございます。

0

自己解決

NextApiResponse、http、net、Socket.IO の各ソースコードを精査し、型拡張を行うことで、型安全を確保できました。
NextApiResponse に必要だったのは、Socket.IOのSocketではなく、netの方のSocketでした。
最終的にコードは以下の様になりました。

Typescript

1import type { NextApiRequest, NextApiResponse } from 'next' 2import type { Server as HTTPServer } from 'http' 3import type { Socket as NetSocket } from 'net' 4import { Server as IOServer } from 'Socket.IO' 5 6interface SocketServer extends HTTPServer { 7 io?: IOServer | undefined 8} 9 10interface SocketWithIO extends NetSocket { 11 server: SocketServer 12} 13 14interface NextApiResponseWithSocket extends NextApiResponse { 15 socket: SocketWithIO 16} 17 18export default function socketHandler(req: NextApiRequest, res: NextApiResponseWithSocket ) { 19 if (res.socket.server.io) { 20 console.log('Socket is already running') 21 } else { 22 console.log('Socket is initializing') 23 const io = new IOServer(res.socket.server) 24 res.socket.server.io = io 25 26 io.on('connection', (socket) => { 27 socket.on('input-change', (msg) => { 28 socket.broadcast.emit('update-input', msg) 29 }) 30 }) 31 } 32 res.end() 33}

使用しているライブラリが動作の中で、どんなオブジェクトを生成しているのかなど、デバッガなどを利用しながら段階的にソースを追っていかないと、正しく型を拡張するのは、なかなか難しい様です。

npmなどのエコシステムがある一方で、型安全にするために多大な工数が掛かってしまうケースもあります。
最近は、型情報などもnpmで公開してくれているライブラリもありますが、今回の様にライブラリ同士の相互作用で、引数としている型の中に未定義の型が紛れ込み、自前で拡張しないといけないケースもある様です。

プロジェクトの規模や目的、効率などを総合的に判断して、anyも使用を考えていけば良いかと思いました。

投稿2022/12/06 07:56

編集2022/12/06 08:07
katatema01

総合スコア23

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。