2017-09-30 10 views
2

TL; DRコンパイルされたPureScriptモジュールにTypeScriptタイピングを作成し、npmパッケージに配布したいとします。私は手動でこれらの型を維持することに満足しています。私はtsconfig.json(アップストリームとダウンストリーム)とpackage.jsonに何を入れる必要があるのか​​分かりません。PureScriptからコンパイルされたJavaScriptモジュールを使用するTypeScriptプロジェクトを設定するにはどうすればよいですか?


Iは、コア機能は、活字体CLIとPureScriptに実装されprojectがあり、このすべては、最終的にNPMを介したJavaScriptとして配布されています。私は安全に活字体からそれらを使用することができますので、私はPureScriptモジュールの活字体のタイプを定義types/People.d.ts

module People where 

type Person = { name :: String } 

david :: Person 
david = { name: "David "} 

:私はコア機能を定義src/People.purs

. 
├── cli     # TypeScript CLI project 
│   ├── main.ts 
│   └── tsconfig.json 
│ 
├── output    # Compiled PureScript modules 
│   └── People 
│    ├── externs.json 
│    └── index.js 
│ 
├── src     # PureScript source 
│   └── People.purs 
│ 
└── types     # TypeScript types for PureScript modules 
    └── People.d.ts 

:私はシンプルなレイアウトでsimilar projectを作成しました:

declare module "People" { 
    export interface Person { 
     name: string; 
    } 

    export const david: Person; 
} 

最後に、cli/main.tsに、私はTypeScでコンパイルさPureScriptモジュールをインポートしたいです私が定義したRIPT種類:彼らは絶対paths-を使用していないので、

import * as People from "People"; 

console.log(People.david); 

私はこれが構築するために、私は究極のJavaScript(node cli/main.js)を実行しようとすると、tscによって生成require呼び出しが失敗得ることができますこの場合、require("People")require("./People")である必要があります。 TypeScriptでimportステートメントを相対化すると、入力の関連付けが解除されます。

私は、これらの目標を達成に苦労しています:

  • は活字体からインポートされたすべてのPureScriptモジュール用の活字体のタイピングを維持します。
  • TypeScriptの型チェックが確実に行われるようにしてください。
  • 実行時にrequireがPureScriptモジュールを呼び出すようにしてください。
  • TypeScriptコンシューマがこれらのタイプ入力を使用できるように、npmパッケージでTypeScriptタイピングを配布します。

TypeScriptのPureScriptモジュールが必要な経験があり、これをnpm経由で配布する経験があれば、本当に参考になります!

答えて

0

モジュールではなく名前空間を宣言すると、すべてが機能します。例えば、types/People.d.ts中:PureScriptモジュールをコンパイルした後

declare namespace People { 
    export interface Person { 
     name: string; 
    } 

    export const david: Person; 
} 

export = People; 
export as namespace People; 

と活字体をコンパイルする前に、I cp types/People.d.ts output/People/index.d.ts。これにより、TypeScriptコードは同じ絶対インポート(例:import * as People from "People";)に満足し、TypeScriptライブラリも追加の設定なしでこれらのタイプを参照します。

いくつかの問題は、しかし、残る:

  • が、私はまだ(ポストビルドステップで../を付加することで)コンパイル活字体でPureScriptモジュールのインポートを相対化する必要があります。私の図書館の消費者は、npmを通過し、それが魔法のように機能するので、これを行う必要はありません。
  • ピリオドを含む名前空間をエクスポートする方法を理解できないため、Data.Maybeのようなモジュールは、Data_Maybeのような名前空間で表されます。
  • 名前空間とモジュールについてはあまりよく分かりませんので、その他の注意点があるかもしれません。
1

あなたのPurescriptモジュールは「人」と呼ばれますが、「人」である必要があります。私はあなたが部分的にそこに入るかもしれない相対的なパスのインポートと思うが、d.tsファイルに相対パスの型を入れることはないと思う。

私はあなたのプロジェクトをチェックアウトし、モジュールの名前を変更し、その後、私はtrueにallowJsを設定し、モジュールをインラインで入力された:

import * as OutputPeople from "../output/People"; 

type Person = { 
    name: string; 
}; 

type PeopleModule = { 
    david: Person 
} 

const People: PeopleModule = OutputPeople 

console.log(People.david); 

私はここに枝に私の修正を置く:https://github.com/justinwoo/ps-js-ts-interop/commit/fc7c1239f9d1bac1cf2bea35f7a07d30c46a5f64

+0

ああ、はい、タイプミスがありますが、それは問題ではありません。あなたが提案した手動キャスティングを試してみましたが、それは機能しましたが、タイピングはnpmで配布されなかったので、私のライブラリのクライアントはそのタイプを取得しませんでした。 –

1

あなたの場合絶対パスを使用してPureScriptパッケージを必要とする必要があります。import * as People from 'People')、私はあなたがノードモジュール解決アルゴリズムをハックする必要があると考えています(たとえば、node_modulesサブディレクトリにPureScript出力を配置して、./output)。

しかし、それは重要ではありません、あなたは相対的な輸入(import * as People from './People'のような)と罰金している場合は、次の操作を行うことができます。PureScriptモジュールの

  1. 使用相対輸入:

    CLIを/main.ts:あなたのタイプと並んで

    import * as People from './People'; 
    
  2. 置きますPureScriptの種類側スクリプトのソース:

    . 
    ├── People 
    │   └── index.d.ts 
    ├── main.ts 
    └── tsconfig.json 
    
  3. は、ローカルモジュール宣言の代わりに、グローバルであるためにあなたのPureScriptの種類を変更し

    CLI /人々/ index.d.ts:今

    export interface Person { 
        name: string; 
    } 
    
    export const david: Person; 
    
  4. 、ノードモジュールの解像度で動作させるには、両方のコンパイラからのJS出力を同じディレクトリに配置する必要があります。私たちはまた、TypeScriptがTSファイルの型宣言を出すことを望んでいます(npmにパブリッシュされたときに消耗することになります)。また、paths TSコンパイラオプション(不要になった)を削除し、ノードタイプのグローバルタイプ参照を追加しています。

    CLI/tsconfig.json:ほとんど行わ

    { 
        "compilerOptions": { 
        "target": "es5", 
        "lib": ["es2015"], 
        "moduleResolution": "node", 
        "baseUrl": ".", 
        "outDir": "./../output", 
        "types": [ 
         "node" 
        ], 
        "declaration": true 
        }, 
        "include": [ 
         "*.ts" 
        ] 
    } 
    
  5. 。ここでは、PureScriptモジュールのタイプ定義が、出力ディレクトリで消費可能になるようにする必要があります。 TypeScriptはタイプ定義出力を生成するときに出力に.d.tsファイルをコピーしません(これらはTSコンパイラによって作成されていないため) - これを補う必要があります。 (?あるいは良い)私はこれが最善であるかどうか、これを達成する方法を知らないが、私のために働い以下:

    package.json:

    "scripts": { 
        "build": "pulp build && tsc -P cli/tsconfig.json && cd cli && rsync -am --include='*.d.ts' -f 'hide,! */' . ./../output" 
    }, 
    ... 
    
  6. 最後にではなく、少なくとも、私たちは、JSのためとNPMの消費者のための型定義のためのエントリポイントを指定する必要があります。

    package.json:

    "main": "output/main.js", 
    "typings": "output/main.d.ts", 
    "files": [ 
        "output/" 
    ] 
    ... 
    

これは、混在言語と混在型のnpmパッケージの作成に関するすべての詳細をカバーしているとは思えませんが、これが出発点になることを願っています。

+0

ええ、これは間違いなく私が知る限り他の設定でこれが行われる方法です。また、個々のタイプに適した型を持っているかどうかを確認するために、私のTypescript codegenライブラリを使用するようなアプローチが最善の方法と思われます:https://github.com/justinwoo/ps-js-ts-interop/tree/ ohyes-codegen – kakigoori

+0

ああ、おそらく、この 'ローカルモジュール'の概念は私の名前空間のアプローチよりも良いでしょうか?どちらにも利点がありますか? –

+0

@DavidSiegel私の答えのアプローチは、モジュールとファイルシステムの1対1のマッピングを可能にします。これらをTypeScriptやJavaScriptで書くかのようにします。また、これらのモジュールをTypeScriptからどのようにインポートするかは、正しいマッピングwr/tです(あなたのケースで正しいインポート方法は 'import * as People from '。/ People''です)。ネームスペースを使用するアプローチは、それらをグローバルに利用できるようにします(たとえば、どこからでもトップレベルのモジュールでインポート可能)。完全にフラットなモジュール構造(ネーミングの競合、名前空間の汚染)がある場合はおそらく必要ではありません。 – MisterMetaphor

関連する問題