Node.js 如何配置使用从PureScript编译的JavaScript模块的TypeScript项目?
TL;DR我想为编译后的PureScript模块创建TypeScript类型,并将它们分发到我的npm包中。我非常乐意手动维护这些输入,我只是不知道我需要在tsconfig.json(上行和下行)和package.json中输入什么Node.js 如何配置使用从PureScript编译的JavaScript模块的TypeScript项目?,node.js,typescript,npm,purescript,Node.js,Typescript,Npm,Purescript,TL;DR我想为编译后的PureScript模块创建TypeScript类型,并将它们分发到我的npm包中。我非常乐意手动维护这些输入,我只是不知道我需要在tsconfig.json(上行和下行)和package.json中输入什么 我有一个示例,其中核心功能在PureScript中通过typescriptcli实现,所有这些最终都通过npm作为JavaScript分发。我创建了一个布局更简单的: . ├── cli # TypeScript CLI pro
我有一个示例,其中核心功能在PureScript中通过typescriptcli实现,所有这些最终都通过npm作为JavaScript分发。我创建了一个布局更简单的:
.
├── 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
在src/People.purs中,我定义了核心功能:
module People where
type Person = { name :: String }
david :: Person
david = { name: "David "}
在types/People.d.ts
中,我为PureScript模块定义了TypeScript类型,以便可以从TypeScript安全地使用它们:
声明模块“人”{
出口接口人员{
名称:字符串;
}
出口承包商大卫:个人;
}
最后,在cli/main.ts
中,我想导入已编译的PureScript模块,其中包含我定义的TypeScript类型:
import*作为“人”中的人;
console.log(People.david);
我可以构建它,但是当我尝试运行终极JavaScript(node cli/main.js
)时,tsc
生成的require
调用失败,因为它们不使用绝对路径--require(“人”)
在这种情况下应该是require(./People”)
。使TypeScript中的import
语句成为相对语句将解除打字的关联
我很难实现这些目标:
- 维护从TypeScript导入的所有PureScript模块的TypeScript类型
- 确保TypeScript类型检查
- 确保在运行时解析对PureScript模块的
require
调用
- 使用npm包分发TypeScript类型,以便TypeScript使用者也可以使用这些类型
如果您有需要TypeScript中的PureScript模块并通过npm分发所有这些模块的经验,我将非常感谢您的指导 您的Purescript模块称为“Person”,但应该是“People”。我认为通过相对路径导入,您可能会部分实现,但我不认为存在在d.ts文件中键入相对路径这样的事情
我签出了您的项目并重命名了模块,然后我将allowJs
设置为true并内联键入模块:
import * as OutputPeople from "../output/People";
type Person = {
name: string;
};
type PeopleModule = {
david: Person
}
const People: PeopleModule = OutputPeople
console.log(People.david);
我把我的修改放在这里的一个分支上:如果您确实需要使用绝对路径来要求您的PureScript包(例如,import*as People from'People'
),我认为您需要绕过节点模块解析算法(例如,将PureScript输出放在节点中的模块
子目录下的/output
)
但是,如果这一点不那么重要,并且您对相对导入(例如,“/People”
”中的人员)没有意见,那么您可以执行以下操作:
对PureScript模块使用相对导入:
cli/main.ts:
将PureScript类型与TypeScript源并排放置:
.
├── People
│ └── index.d.ts
├── main.ts
└── tsconfig.json
将PureScript类型更改为本地模块声明,而不是全局声明:
cli/People/index.d.ts:
现在,要使用节点模块解析,您需要将两个编译器的JS输出放在同一个目录中。我们还希望TypeScript为TS文件发出类型声明(在npm上发布时可以使用)。我们还删除了路径
TS编译器选项(不再需要),并为节点类型添加全局类型引用
cli/tsconfig.json:
差不多完成了。现在,我们需要确保PureScript模块的类型定义最终位于输出目录中,以便使用。在生成类型定义输出时,TypeScript不会在其输出中复制.d.ts
文件(因为这些文件不是由ts编译器创建的)–我们需要对此进行补偿。我不知道这是否是实现这一目标的最佳(甚至是一个好的?)方式,但以下几点对我很有用:
package.json:
最后但并非最不重要的一点是,我们需要为JS和npm使用者的类型定义指定入口点:
package.json:
我相信这并没有涵盖创建混合语言和混合类型npm包的所有细节,但希望这可以作为一个起点。声明名称空间而不是模块可以让一切正常工作。例如,在类型/People.d.ts中:
声明命名空间人员{
出口接口人员{
名称:字符串;
}
出口承包商大卫:个人;
}
出口=人;
作为名称空间人导出;
在编译PureScript模块之后,在编译TypeScript之前,Icp types/People.d.ts output/People/index.d.ts
。这使得TypeScript代码可以使用相同的绝对导入(例如,import*作为“People”;
)而不需要额外配置就可以看到这些类型
尽管如此,仍存在一些问题:
- 我仍然需要在编译后的TypeScript中相对化PureScript模块导入(通过在后期构建步骤中预先添加
。/
);不过,我的库的使用者不必这样做,因为它通过npm
,这神奇地使它工作起来
- 我不知道如何导出带句点的名称空间,因此像
Data.Maybe
这样的模块由像Data\u可能
这样的名称空间表示
- 我不太了解名称空间和模块,所以可能还有其他的注意事项
啊,是的,我看到了打字错误,但这不是问题所在。我尝试了你建议的手动铸造,效果很好,但打字没有随npm一起分发,所以我图书馆的客户没有得到打字。是的,据我所知,这肯定是在其他设置中完成的方式。对于ma来说
.
├── People
│ └── index.d.ts
├── main.ts
└── tsconfig.json
export interface Person {
name: string;
}
export const david: Person;
{
"compilerOptions": {
"target": "es5",
"lib": ["es2015"],
"moduleResolution": "node",
"baseUrl": ".",
"outDir": "./../output",
"types": [
"node"
],
"declaration": true
},
"include": [
"*.ts"
]
}
"scripts": {
"build": "pulp build && tsc -P cli/tsconfig.json && cd cli && rsync -am --include='*.d.ts' -f 'hide,! */' . ./../output"
},
...
"main": "output/main.js",
"typings": "output/main.d.ts",
"files": [
"output/"
]
...