Definitelytyped: [@ types / koa-router]コアと互換性のないタイプ

作成日 2019年06月13日  ·  23コメント  ·  ソース: DefinitelyTyped/DefinitelyTyped

問題を修正する方法を知っている場合は、代わりにプルリクエストを行ってください。

  • [x] @types/koa-routerパッケージを使用しようとしましたが、問題が発生しました。
  • [x] tscの最新の安定バージョンを使用してみました。 https://www.npmjs.com/package/typescript
  • [x] StackOverflowに不適切な質問があります。 (そこで適切な質問をしてください)。
  • [x] [メンション](https://github.com/blog/821-mention-somebody-they-re-notified)著者( index.d.ts Definitions by:index.d.ts )応答。

    • 著者: @hellopao @schfkt @JounQin @ romain-faust @Falinor

ソースコード

import Router from 'koa-router'
import { Context } from 'koa'

const router = new Router()

router.get(
  '/auth',
  async (ctx: Context): Promise<void> => {
    ctx.body = 'aaa'
  }
)

エラーメッセージ

Argument of type '(ctx: Context) => Promise<void>' is not assignable to parameter of type 'Middleware<ParameterizedContext<any, IRouterParamContext<any, {}>>>'.
  Types of parameters 'ctx' and 'context' are incompatible.
    Property 'log' is missing in type 'BaseContext & { app: import("/Users/li.li/Work/poking/node_modules/@types/koa/index.d.ts")<any, {}>; request: Request; response: Response; req: IncomingMessage; res: ServerResponse; ... 4 more ...; respond?: boolean | undefined; } & IRouterParamContext<...>' but required in type 'Context'.ts(2345)

最も参考になるコメント

koaは、 ctx複数のタイプを提供します。 現時点では、 ContextParameterizedContextだけを気にする必要があります
一部のライブラリは、 typescript宣言のマージによってContext拡張ます。 たとえば、 koa-sessionはそれを行います

declare module "koa" {
    interface Context {
        session: session.Session | null;
        readonly sessionOptions: session.opts | undefined;
    }
}

幸運にも不幸にも、 koa-routerはミドルウェアでctxオブジェクトを入力するためにContext ParameterizedContext代わりにContextを使用します(実際にはkoaによって提供されますが、そうではありません)ここでは関係ありません)。 そのため、次のコードにエラーが表示されます

import Router from 'koa-router';
import { Context } from 'koa';

const router = new Router();

router.post('/', (ctx: Context) => { // error: Argument of type '(ctx: Context) => void' is not assignable to parameter of type 'Middleware<ParameterizedContext<any, IRouterParamContext<any, {}>>>' because it is missing the following properties from type 'Context': session, sessionOptions
    ctx.body = 'Hello worls';
});

この問題を解決するには、汎用ルータークラスの機能を使用する必要があります。

import Router from 'koa-router';
import { DefaultState, Context } from 'koa';

const router = new Router<DefaultState, Context>();

router.post('/', (ctx: Context) => {
    ctx.body = 'Hello world';
});

BaseContext (または新しいバージョンではDefaultContext )の使用を推奨する人もいます。 好きなものを置くことができる[key: string]: any;あるだけなので、避けることをお勧めします。 Typescriptは実際にそのようなことを避けるために開発されました

@types/[email protected]を使用する場合は、このような問題は発生しない可能性があります。 しかし、それは新しいバージョンで同じ[key: string]: any;DefaultContextに移動されたためです

全てのコメント23件

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "moduleResolution": "node",
    "strict": true,
    "strictPropertyInitialization": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "sourceMap": true
  },
  "include": [
    "src"
  ]
}

このエラーも発生しますが、代わりにBaseContextを使用でき、動作します。これが予期されるかどうかはまだわかりませんが、koaとkoaの両方のルーターコンテキストでどちらのインターフェイスを使用する必要があるかは明確ではありません。

エラーは、 ParameterizedContext期待していることを示しています。これは、使用すると機能します。

Koa定義ファイルで、この行interface Context extends ParameterizedContext {}を見つけたので、 Context自体を使用するのにできるだけ近いです。

@ ejose19BaseContextはいくつかのものがありません。 Koa定義ファイルでinterface Context extendsを検索し、そこから逆方向に読み取ると、 ContextBaseContext以上に拡張されていることがわかります。

(私はTypeScriptにまったく慣れていないので、このことを本当に知りません。エラーとソースコードを読んで、物事を理解しようとしているだけです。)

はい、パラメータ化されたコンテキストにはBaseContextよりもはるかに多くのものがありますが、ログイン/ログイン/ログアウト/ログアウト(コンテキストのみにあります)などの重要なものがまだありませんが、ctxを使用しようとすると:koa-router内のコンテキストがルーティングします互換性がないと言います。 正しいインターフェースを使用する必要があるため、誰かがこれを修正することを願っています。

もう少し掘り下げてみると、koa-session / koa-generic-session / koa-passport(そしておそらくもっとたくさん)のようなライブラリが独自のインターフェースコンテキストを作成/拡張していることがわかりました(これは@ types / koa-passportからの抜粋です)

declare module "koa" {
    interface Context {
        login(user: any, options?: any): Promise<void>;
        logIn: Context["login"];

        logout(): void;
        logOut: Context["logout"];

        isAuthenticated(): boolean;
        isUnauthenticated(): boolean;
    }
}

そのため、ParametrizedContextタイプにはこれらすべてのライブラリタイプがありません。typescriptに関する私の知識はこの問題を解決するのに十分ではありませんが、この情報が適切な解決につながることを願っています。

まだこの問題に悩まされている人は、 ctxパラメーターの型定義を削除するだけで問題が解決します。

baseRouter.get( '/auth', async (ctx): Promise<void> => { ctx.body = 'aaa' } )

requireを使用する場合、新しいKoa()koa-websocketの使用に問題はありません: const Koa = require("Koa")

この問題を修正する別の方法を見つけました。 node_modulesとロックファイル(存在する場合)を吹き飛ばして、すべてを再インストールします。

問題は、 koa-routerkoa-composekao-websocketsなどのすべての@types koa添加剤に、すべて"@types/koa": "*"への依存関係が含まれていることです。 NPM / Yarnはこれらを現在のバージョンでダウンロードし、 Koa-routerタイプモジュールのローカルに保存します。

koaタイプを新しいバージョンに更新しても、追加パッケージの古いダウンロード

node_modulespackage-lock.jsonを削除してから、 npm install再インストールしても問題は解決しません。

次のコードを使用して、 `koa-session 'でこの問題を再現できます。

`` ` lang:javascript
// npm install koa koa-session koa-router
// npm install -D @ types / koa @ types / koa-session @ types / koa-router
'koa'からKoaをインポートします。
'koa-session'からセッションをインポートします。
'koa-router'からルーターをインポートします。

const app = new Koa();
const router = new Router();

app.keys = ['key1'、 'key2'];

const CONFIG = {
キー: ' koa:sess '、
maxAge:86400000
};

app.use(session(CONFIG、app));

router.get( '/'、(ctx)=> {
ctx.body = 'ようこそ';
ctx.session.name = 'abc';
});

app.use(router.routes())
.use(router.allowedMethods());

app.listen(3000);

When run this code with `ts-node`, it will generate following error:

koarouterissue.ts(21,7):エラーTS2339:プロパティ 'session'はタイプ 'ParameterizedContextに存在しません `` `

koa-passportと同じです。

Property 'login' does not exist on type 'ParameterizedContext<any, IRouterParamContext<any, {}>>'.

ここで同じ問題

連絡あった? 私も同じ問題を抱えています。

問題は2.0.52のようです。

2.0.50に強制された場合

  "resolutions": {
    "@types/koa": "2.0.50"
  },

また、依存関係で2.0.50に強制します

"@types/koa": "2.0.50",

それは再び動作します!

同じ問題。 "@types/koa": "2.0.50"使用するとこの問題を修正できますが、 koa.Nextを使用してnext()関数を入力することはできません。

はい、これとまったく同じ問題が発生しており、これが修正されるまで2.0.50強制的にロックされています。

の解き方?

@hengkx最初に削除した場合は、次のようにします。 yarn add @types/[email protected]とりあえずロックします。 私の考えでは、これが修正されたことがわかったら、package.jsonに^を追加し直します。

@ lili21
koa-routerはRouterContext型でハンドラー関数を呼び出しますが、定義したハンドラー関数にはContext型が必要です。 Context型は、 RouterContextにない他のいくつかのプロパティを定義している可能性があるため、型チェックは成功しません。

これは交差型で解決できます。

import { RouterContext } from "koa-router";
router.get(
  '/auth',
  async (ctx: Context & RouterContext): Promise<void> => {
    ctx.body = 'aaa'
  }
)

koaは、 ctx複数のタイプを提供します。 現時点では、 ContextParameterizedContextだけを気にする必要があります
一部のライブラリは、 typescript宣言のマージによってContext拡張ます。 たとえば、 koa-sessionはそれを行います

declare module "koa" {
    interface Context {
        session: session.Session | null;
        readonly sessionOptions: session.opts | undefined;
    }
}

幸運にも不幸にも、 koa-routerはミドルウェアでctxオブジェクトを入力するためにContext ParameterizedContext代わりにContextを使用します(実際にはkoaによって提供されますが、そうではありません)ここでは関係ありません)。 そのため、次のコードにエラーが表示されます

import Router from 'koa-router';
import { Context } from 'koa';

const router = new Router();

router.post('/', (ctx: Context) => { // error: Argument of type '(ctx: Context) => void' is not assignable to parameter of type 'Middleware<ParameterizedContext<any, IRouterParamContext<any, {}>>>' because it is missing the following properties from type 'Context': session, sessionOptions
    ctx.body = 'Hello worls';
});

この問題を解決するには、汎用ルータークラスの機能を使用する必要があります。

import Router from 'koa-router';
import { DefaultState, Context } from 'koa';

const router = new Router<DefaultState, Context>();

router.post('/', (ctx: Context) => {
    ctx.body = 'Hello world';
});

BaseContext (または新しいバージョンではDefaultContext )の使用を推奨する人もいます。 好きなものを置くことができる[key: string]: any;あるだけなので、避けることをお勧めします。 Typescriptは実際にそのようなことを避けるために開発されました

@types/[email protected]を使用する場合は、このような問題は発生しない可能性があります。 しかし、それは新しいバージョンで同じ[key: string]: any;DefaultContextに移動されたためです

@zfeedソリューションは非常にうまく機能し、すべてのライブラリメソッド(セッション、パスポート)にctxルーターミドルウェア内でアクセスできるようになりました。また、各ルートではなくルーターごとに1回インターフェースを宣言するだけで、この問題を非常にエレガントに処理できます。 乾杯!

ルート外でルートコールバックを定義するユーザー向けのメモ(このように)

function getUser(ctx: Context){...}

router.post('/user/:id', getUser)

その場合、typescriptは宣言のマージについて認識せず、Contextにはルーター固有のプロパティ(ctx.paramsなど)が含まれません。

1つの解決策は、 @ zfeedで言及されているタイプを適用するカスタム定義の「RouterContext」を使用すること

export type RContext = ParameterizedContext<
  DefaultState,
  Context & Router.IRouterParamContext<DefaultState, Context>
>;

function getUser(ctx: RContext) {
  ctx.params; // <--- this will be found
}

そして今、ルーターのプロパティとkoaの両方がRContextとして利用可能になります

@ ejose19ありがとうございます。

ありがとう@zfeed

このページは役に立ちましたか?
0 / 5 - 0 評価