javascript - typescript 命名空间引用不起作用

标签 javascript typescript class namespaces typescript-typings

我正在尝试使用 typescript 命名空间。当我不导入其他模块但在我的案例中导入其他模块时,它工作得很好sort导出的函数 get即使它们在相同的命名空间中,也不能在其他文件中使用。

import { sort } from "../sort"

namespace Api {
    export async function get(url:string){
        const res = await fetch("api/"+url)
        return await res.json()
    }
    export class Users {
        private uid: string
        constructor(uid: string){
            this.uid = uid
        }
        public async getUserProfile(){
            return await get(`/u/${this.uid}/profile`)
        }
        public async getUserSongs(){
            return await get(`/u/${this.uid}/musics`)
        }
    }
}



/// <reference path="api.ts" />

namespace Api {
    export class Track{
        private track_id: string
        constructor(track_id){
            this.track_id = track_id
        }
        public async hasLiked(){
            return await get("/track/"+this.track_id+"/hasLiked")
        }
    }
}

它说 could not find name get但是当我不导入时 sort它完美地工作

namespace Api {
    export async function get(url:string){
        const res = await fetch("api/"+url)
        return await res.json()
    }
    export class Users {
        private uid: string
        constructor(uid: string){
            this.uid = uid
        }
        public async getUserProfile(){
            return await get(`/u/${this.uid}/profile`)
        }
        public async getUserSongs(){
            return await get(`/u/${this.uid}/musics`)
        }
    }
}

最佳答案

当您向文件中添加 import 语句时,它会变成 .ts文件到一个模块中,并将文件中的所有声明“移动”到该模块的范围内。
所以namespace Api在其模块定义之外看不到并将其从全局命名空间中删除。有几种方法可以处理:

  • 可以转你主Api通过将扩展名更改为 d.ts 将文件转换为定义文件并包装 namespace Api进入 declare global {} .这样你甚至不需要三重斜线导入,它仍然可以在全局范围内使用。您的新 api.d.ts应该是这样的:

  • import { sort } from "./sort";
    
    declare global {
      namespace Api {
        export async function get(url: string) {
          const res = await fetch("api/" + url);
          return await res.json();
        }
        export class Users {
          private uid: string;
          constructor(uid: string) {
            this.uid = uid;
          }
          public async getUserProfile() {
            return await get(`/u/${this.uid}/profile`);
          }
          public async getUserSongs() {
            return await get(`/u/${this.uid}/musics`);
          }
        }
      }
    }

  • 省略顶级导入并使用动态导入,如下所示:

  • namespace Api {
      export async function get(url: string) {
        const sort = await import("./sort");
        const res = await fetch("api/" + url);
        return await res.json();
      }
      export class Users {
        private uid: string;
        constructor(uid: string) {
          this.uid = uid;
        }
        public async getUserProfile() {
          return await get(`/u/${this.uid}/profile`);
        }
        public async getUserSongs() {
          return await get(`/u/${this.uid}/musics`);
        }
      }
    }

  • 简单转动namespace ApiTrack进入 d.ts解决问题

  • 在 typescript 中使用声明合并和模块非常复杂,我认为仍然有很多解决方法和陷阱,所以我的答案肯定可以扩展。

    关于javascript - typescript 命名空间引用不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68336381/

    相关文章:

    javascript - Windows 8.1 上的 Jest 最小报告

    ruby - 描述ruby中的类关系

    java - 仅当外部类参数化时内部接口(interface)才会生成错误?为什么?

    javascript - Chrome DevTools 不显示 .js 文件

    javascript - 使用 javascript 或 jquery 在 webview 中显示本地 android 图像

    javascript - 在 map() 函数中为 axios 请求设置延迟/超时

    reactjs - 只允许特定元素作为由 Typescript 检查的 prop

    javascript - 将 GIF 播放器 Web 组件转换为 React 组件?

    c++ - 存储大的相似对象的更好方法

    javascript - jquery - 将 json 转换为 javascript 数组所需的帮助