如何导入Dropbox API类型的Typescript定义?

5jdjgkvh  于 2023-04-22  发布在  TypeScript
关注(0)|答案(2)|浏览(107)

我正在用Typescript中的VS Code制作一个使用Dropbox SDK的浏览器应用程序。
此导入工作原理:

import { Dropbox, DropboxAuth, DropboxResponse, DropboxResponseError } from 'dropbox';

这个上传代码也可以工作:

const uploadResult = await dropbox.filesUpload(
   {path: constants.dropboxFilename, contents: journalString});

但当我写这个,允许覆盖上传和防止409错误:

const uploadResult = await dropbox.filesUpload(
   {path: constants.dropboxFilename, contents: journalString, mode: WriteModeOverwrite});

我无法访问WriteModeOverwrite的定义,因为它位于node_modules/dropbox/types/dropbox_types.d.ts
如何将这个定义文件添加到我的项目中,以便VS Code和TSC都能看到它?
我的项目似乎只能自动看到node_modules/dropbox/types/index.d.ts。谢谢。
更多信息:
我也尝试添加import * as dropboxTypes from 'dropbox/types/dropbox_types';,但dropboxTypes.任何内容都是空的,自动完成也找不到任何文件模式。
mode属性有提示:files.CommitInfo.mode?: files.WriteMode | undefined,但是如果我尝试将其设置为files.WriteModeWriteModeOverwritefiles.WriteModeOverwrite,这是一个类型错误。VS Code无法自动完成files上的任何内容。
如果我将属性设置为'overwrite',代码不会编译而没有错误,但可以完美地运行和上传。

von4xj4u

von4xj4u1#

我同情你,因为这是(可以理解的)一个不明确的类型。似乎这个库的类型是生成的,出版商没有彻底考虑使用的人体工程学。
来自dropbox/dropbox-sdk-js#207(注解):
WriteMode是一个union,而不是一个字符串,所以你需要像这样指定它:

this.dropbox.filesUpload({contents: fileContent, path: fileName, mode:{".tag": "overwrite"}})

Dropbox真的应该提供一个导出的枚举供您在这里使用。
This answer已经解释了如何导入files命名空间并找到所需的类型--太棒了!
但是如果您没有访问该类型的权限(或者该类型的名称在将来发生了更改,等等),该怎么办呢?
你可以使用TypeScript来推断所需的类型,使用几个utility types。下面是一个例子:
TSPlayground

import type { Dropbox } from "dropbox";

// This is the type that represents the first parameter for the `filesUpload` method:
type UploadArg = Parameters<Dropbox["filesUpload"]>[0];
   //^? type UploadArg = files.UploadArg

// This type represents the `mode` property of the type above:
type WriteMode = UploadArg["mode"];
   //^? type WriteMode = files.WriteMode | undefined

// However, it's still not obvious what `files.WriteMode` means...
// Utility types can be used to determine that:

type WriteModeKey = keyof NonNullable<WriteMode>;
   //^? type WriteModeKey = ".tag"

type WriteModeTagValue = NonNullable<WriteMode>[".tag"];
   //^? type WriteModeTagValue = "overwrite" | "add" | "update"

// Bingo! We need a type like this:
type WriteModeOverwrite = Extract<WriteMode, { ".tag": "overwrite" }>;
   //^? type WriteModeOverwrite = files.WriteModeOverwrite

// It can be used to annotate your `mode` value like this:
const mode: WriteModeOverwrite = { ".tag": "overwrite" };

declare const dropbox: Dropbox;
declare const otherProps: Pick<UploadArg, "path" | "contents">;

dropbox.filesUpload({
  ...otherProps,
  mode,
}); // Ok
vhmi4jdf

vhmi4jdf2#

根据我所看到的,你应该不需要做任何事情来让它工作。types/index.d.ts做了export * from './dropbox_types';,而WriteModeOverwrite是从files命名空间内的types/dropbox_types.d.ts导出的。我认为你只需要将files添加到你的导入列表中(在import {...} from 'dropbox'中),然后使用files.WriteModeOverwrite.ex。

import { type files } from "dropbox"
let foo: files.WriteModeOverwrite;

let foo只是在类型上下文中使用类型的一个示例(“foo”是一个非常标准的示例变量名)。你可以在任何你想要的类型上下文中使用files.WriteModeOverwrite。事实上,你不能在你想要使用它的地方使用它,因为你不应该那样使用它-那不是类型上下文。那是值上下文(对象的键值项的值部分)...你到底想做什么?你需要在那里放一个 * 值 * 然后type-annotate/ type-assert它。
不幸的是,我实际上不知道你应该在那里使用什么。它要么是"overwrite",要么是{".tag": "overwrite"}.Searching public GitHub repos, I see both in usagethe official upload example没有显示该参数的用法(在撰写本文时)。尝试这两种方法,看看哪一种确实能达到你的期望。

相关问题