【问题标题】:Extending Array in TypeScript for specific type在 TypeScript 中为特定类型扩展数组
【发布时间】:2021-10-17 17:38:01
【问题描述】:

我知道如何为任何类型扩展数组:

declare global {
  interface Array<T> {
    remove(elem: T): Array<T>;
  }
}

if (!Array.prototype.remove) {
  Array.prototype.remove = function<T>(this: T[], elem: T): T[] {
    return this.filter(e => e !== elem);
  }
}

来源:Extending Array in TypeScript

但是还有一种方法可以仅针对特定类型扩展数组吗?。仅适用于 User -> Array&lt;User&gt; 类型的数组。

我想创建一个扩展方法,比如.toUsersMap(),并且这个方法不应该显示给没有User类型的数组。

【问题讨论】:

    标签: arrays typescript types


    【解决方案1】:

    您可以实现类似的行为:

    type User = {
      tag: 'User'
    }
    
    interface Array<T> {
      toUsersMap: T extends User ? (elem: T) => Array<T> : never
    }
    
    declare var user: User;
    
    const arr = [user]
    
    arr.toUsersMap(user) // ok
    
    const another_array = [{ notUser: true }]
    
    another_array.toUsersMap() // This expression is not callable
    

    如果T 参数没有扩展User,TS 将不允许使用toUsersMap

    Playground

    【讨论】:

    • 你也可以像so一样使用a this parameter。
    • @jcalz 我相信您的解决方案比我的要好得多。请提供答案
    【解决方案2】:

    我认为没有办法完全抑制 IntelliSense 在 Arrays 上对 toUsersMap() 的提示,但您绝对可以将调用 arr.toUsersMap() 设为编译器错误,除非 arr 可分配给 @987654327 @。一种方法是给toUsersMap() 方法一个this parameter:

    interface Array<T> {
      toUsersMap(this: Array<User>): Map<string, User>;
    }
    

    现在编译器将要求 toUsersMap() 仅在可分配给 Array&lt;User&gt; 的 this 上下文中调用:

    interface User {
      username: string;
    }
    const arr = [{ username: "foo" }, { username: "bar" }];
    arr.toUsersMap() // okay, no error
    
    const another_array = ["hello", 123];
    another_array.toUsersMap() // error, 
    //~~~~~~~~~~~ <--
    // The 'this' context of type '{ notUser: boolean; }[]' is 
    // not assignable to method's 'this' of type 'User[]'
    

    Playground link to code

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多