LoginSignup
1

More than 1 year has passed since last update.

TypeScriptのd.tsでCommonJSスタイルのエクスポートの型を記述する際に引っかかったこと

Last updated at Posted at 2021-12-09

CommonJS対応プルリク

https://bitbucket.org/atlassian/atlassian-connect-express/pull-requests/254
https://bitbucket.org/atlassian/atlassian-connect-express/pull-requests/257

d.tsコードの全貌

type BearerToken = {
    access_token: string;
};

declare class AddOn {}
declare class HostClient {
    getUserBearerToken: (scopes: string[], clientSettings: AddOnFactory.ClientInfo) => Promise<BearerToken>;
}

declare function AddOnFactory(): AddOn;

declare namespace AddOnFactory {
    export type HostClient = InstanceType<typeof HostClient>;
    export interface ClientInfo {
        key: string
    }
    export type AddOn = InstanceType<typeof AddOn>;
    export type AddOnFactory = typeof AddOnFactory;
    export { BearerToken };
}

export = AddOnFactory;

使い方

esModuleInteropfalseでも動きます。

import ace = require('atlassian-connect-express');
import { HostClient, ClientInfo, AddOn, AddOnFactory, BearerToken } from 'atlassian-connect-express';

説明

今回求められたのは、module.exportsで関数をエクスポートしつつ、名前付きエクスポートで型をエクスポートすることです。
これを実現するためには、functionnamespaceを同名で宣言して、export = AddOnFactory構文でエクスポートする必要があります。
また、エクスポートするインターフェースはnamespace内で宣言すると何回も別名を定義する必要がなく、簡潔です。
typeof AddOnFactorytypeof付けないと循環参照になってエラーになります。
最後に、typeof HostClientと書くと型が"function"になってしまうのでInstanceType<typeof HostClient>と書く必要があります。
これ知らなくて知らない人から怒られました:frowning2:

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1