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

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

新規登録して質問してみよう
ただいま回答率
85.48%
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

解決済

2回答

1914閲覧

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

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ライブラリです。

1グッド

0クリップ

投稿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上で試しています。

y-temp4👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

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

総合スコア67

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katatema01

2022/12/06 07:57

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問