微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过 npm 包共享 TypeScript 类型声明 更新 那么...如何通过 npm 共享 TS 类型

如何解决通过 npm 包共享 TypeScript 类型声明 更新 那么...如何通过 npm 共享 TS 类型

我需要在我的 React 客户端和我的 Express REST API 之间共享一些 TypeScript 类型,以保持代码干净和干燥。 由于这是一个私有项目,我不会通过@types 存储库共享这些类型,因此我遵循了 TypeScript 网站上的指南,这就是结果...

在 React 客户端中一切正常:我已将这些类型安装为开发依赖项并完美地使用它们。

在 Express API 中,我收到此错误,我认为这与我构建包的方式有关。

我做错了什么? 尽管我很无知,但我认为这与模块的加载方式有关,但我无法准确找出可能导致错误的原因。

> cross-env NODE_ENV=production node dist/index.js

internal/modules/cjs/loader.js:834
  throw err;
  ^

Error: Cannot find module '@revodigital/suiteods-types'

我如何在 API 代码中导入模块

import { AuthEntity,Roles } from '@revodigital/suiteods-types';

@Model()
export class AuthEntityModel implements AuthEntity {
  /* ... */

  role: Roles;

  /* ... */
}


包树
suiteods-types
  |_index.d.ts
  |_package.json
  |_README.md
  |_tsconfig.json

index.d.ts

export = Ods;
export as namespace Ods;

declare namespace Ods {
  /* ... */
  interface AuthEntity extends DomainObject {
    email: string;
    password: string;
    role: Roles;
    instanceId: string;
  }

  enum Roles {
    BASE,STUDENT,BUSInesS,INSTRUCTOR,ADMIN
  }
  /* ... */
}

package.json

{
  "name": "@revodigital/suiteods-types","version": "0.1.1","description": "Type declarations for suiteods project","types": "index.d.ts","scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },"author": "Revo Digital","license": "ISC","repository": {
    "type": "git","url": "git+https://github.com/revodigital/suiteods-types.git"
  },"bugs": {
    "url": "https://github.com/revodigital/suiteods-types/issues"
  },"homepage": "https://github.com/revodigital/suiteods-types#readme"
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs","lib": [
      "es6"
    ],"noImplicitAny": true,"noImplicitThis": true,"strictnullchecks": true,"strictFunctionTypes": true,"baseUrl": "../","typeRoots": [
      "../"
    ],"types": [],"noEmit": true,"forceConsistentCasingInFileNames": true
  },"files": [
    "index.d.ts"
  ]
}

更新

对如何摆脱命名空间感到困惑,并且仍然在模块上遇到相同的错误,现在安装为 `dependency` 而不是 `devDependency`。 文件结构和上面一样。 先谢谢您的帮助。

更新并完成 index.d.ts

export = Ods;
export as namespace Ods;

declare namespace Ods {

  type IdType = 'Carta Identità' | 'Passaporto' | 'Patente'
  
  type ODSModule = 'SCUOLA' | 'OPERATORI' | 'DRONI' | 'ODS_ROOT'

  type Role = 'BASE' | 'STUDENTE' | 'ISTRUTTORE' | 'AMMINISTRATORE' | 'UTENTE_AZIENDale'
  
  type UserScope = 'INTERNAL' | 'WHOLE'


  interface Address {
    street: string;
    city: string;
    province: string;
    CAP: string;
  }

  interface Credentials {
    email: string;
    password: string;
  }

  interface LoggedEntity {
    authEntity: AuthEntity;
    baseUser: BaseUser;
  }

  interface ModulesInstancesMap {
    SCUOLA: string;
    OPERATORI: string;
    DRONI: string;
    ODS_ROOT: string;
  }

  interface MultiTenantController {

  }

  interface Tenant {
    _id: string;
    role: Role | ODSModule;
  }

  interface TenantInfo {
    tenant: Tenant;
    relativeGodRole: Role;
  }

  interface AuthEntity extends DomainObject {
    email: string;
    password: string;
    role: Role;
    instanceId: string;
  }

  interface BaseUser extends DomainObject {
    firstName: string;
    lastName: string;
    phone: string;
    address: Address;
    scope: UserScope;
  }

  interface BelongsToModule {
    module: ODSModule;
  }

  interface Business extends DomainObject {
    businessName: string;
    pIva: string;
    tel: string;
    pec: string;
    recipientCode: string;
    address: Address;
  }

  interface DomainObject {
    _id: string;
  }

  interface HasTenant {
    tenantInfo: TenantInfo;
  }

  interface Instructor extends BaseUser {
    licenseCode: string;
  }

  interface InternalWholeSuiteUser extends BaseUser {
    modulesInstancesMap: ModulesInstancesMap;
  }

  interface InternalModuleUser extends BaseUser,BelongsToModule {
    moduleInstanceId: string;
  }

  interface School extends Business,HasTenant {
    cApr: number;
  }


  interface Student extends BaseUser {
    stateIssuedIdNumber: string;
    stateIssuedisType: IdType;
    job: string;
    businessId?: string;
  }
}

解决方法

问题

enum 类型不是纯类型。 TypeScript 编译器为此类型生成一些 JavaScript 代码。您的其余代码需要它。

在运行时,正常部署后,您的代码无法访问“开发依赖项”。只安装了依赖项。

就您的前端而言,由于 Webpack,它有一点魔力。在构建时,Webpack 会按照所有依赖项(包括开发依赖项)中的代码进行打包。因此,您的私有依赖项的编译代码在包中并且可以正常工作。

解决方案

解决方案 1:可以仅使用运行时使用的 javascript 代码发布您的包 @revodigital/suiteods-types。然后这个包就可以作为常规的依赖了。

方案二:可以在后端使用一个bundler(Webpack或者Rollup)来打包使用过的代码。私有包的打包方式和前端一样。

解决方案 3:将私有包中的类型设为“纯类型”,以便在运行时根本不需要它。用字符串的联合替换所有 enum 类型。

例如:

enum Roles {
    BASE,STUDENT,BUSINESS,INSTRUCTOR,ADMIN
  }

... 可以替换为:

type Role = "BASE" | "STUDENT" | "BUSINESS" | "INSTRUCTOR" | "ADMIN"

注意:它需要一些重构。

作为奖励的免费建议:不要保留命名空间

不建议在模块中使用 namespace。你应该摆脱它。

当前代码:

export = Ods;
export as namespace Ods;

declare namespace Ods {

  type IdType = 'Carta Identità' | 'Passaporto' | 'Patente'
  
  type ODSModule = 'SCUOLA' | 'OPERATORI' | 'DRONI' | 'ODS_ROOT'

  // ...

  interface Address {
    street: string;
    city: string;
    province: string;
    CAP: string;
  }

  // ...
}

... 应替换为:


export type IdType = 'Carta Identità' | 'Passaporto' | 'Patente'
  
export type ODSModule = 'SCUOLA' | 'OPERATORI' | 'DRONI' | 'ODS_ROOT'

// ...

export interface Address {
  street: string;
  city: string;
  province: string;
  CAP: string;
}

// ...

然后,如果您愿意,可以将模块作为命名空间导入:

import * as Ods from "@revodigital/suiteods-types";
,

除了宝贵的@Paleo 编辑之外,添加一个包含以下内容的 index.js 文件解决了问题。


index.js

module.exports = {};

更新文件结构

suiteods-types
  |_index.d.ts
  |_index.js
  |_package.json
  |_README.md
  |_tsconfig.json


那么...如何通过 npm 共享 TS 类型

如果你想共享一些 TypeScript 类型(例如在我的情况下在客户端和服务器之间),步骤(对我有用)是以下步骤。
  1. 创建一个新文件夹并使用 npm init 将其初始化为 npm 包
  2. 推断您要在实体之间共享的所有类型并将它们分组到一个 index.d.ts 文件中
  3. 仅声明“纯类型”,就我而言,converting the enums into types(并进行一些重构以适应其余代码)就足够了
  4. 添加 tsconfig.json(示例见我上面的问题)
  5. 添加一个仅包含 index.jsmodule.exports = {}
  6. 发布
  7. 将其安装为 dependency,所以 npm i --save @yourscope/yourpkg
  8. 在需要时使用它

为了发布包,我使用了 npm 和 GitHub 包。看到这些链接...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。