网站搜索

typescript - 防止标准库类型的接口合并


我在我的 types.d.ts 文件中有一个名为 Account 的接口:

interface Account {
  id: string;
  name: string;
}

然而,当我使用它时,我也会从 lib.dom.d.ts 获取字段:

{
    displayName: string;
    id: string;
    imageURL?: string;
    name?: string;
    rpDisplayName: string;
    contactRelations: ContactRelation[];
}

我知道这是因为我的 tsconfig.json 中有 "lib": ["dom"],但有没有什么方法可以防止这些类型被合并?

重命名我的域接口是显而易见的解决方法,但我只是好奇是否有更优雅的处理方式。

答案#1

如果你要引入的类型名称与全局类型冲突,你应该考虑使用命名空间和模块。这就要求你通过命名空间引用这些类型,或者在其他文件中通过 import 导入它们,因此虽然这可以说是“正确”的做法,但这是一种绕道的方式来重命名你的接口:

namespace MyNameSpace {
  export interface Account {
    id: string;
    name: string;
  }
}

const account: MyNameSpace.Account = { id: "", name: "" };

如果你需要自己命名为Account的全局类型,也可以选择从本地标准库副本中重命名冲突的接口。例如,你可以编辑这一行:

// Account --> AccountDOM
interface AccountDOM {
    displayName: string;
    id: string;
    imageURL?: string;
    name?: string;
    rpDisplayName: string;
}

以及这行:

interface WebAuthentication {
    getAssertion(assertionChallenge: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer | null, options?: AssertionOptions): Promise<WebAuthnAssertion>;
    // Account --> AccountDOM
    makeCredential(accountInformation: AccountDOM, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer | null, options?: ScopedCredentialOptions): Promise<ScopedCredentialInfo>;
}

这可能不会特别好地扩展,尤其是因为每次更新库时你都需要继续合并这个更改,但标准库是标准的,而不是不可侵犯的;有一些类型,比如 Array 和 String,它们如此深入语言本身,以至于即使在库文件中也无法更改它们。但这个 Account 类型就不是其中之一。

好的,希望有帮助;祝你好运!

代码的 Playground 链接