簡體   English   中英

Typescript:從 Map 或 object 獲取密鑰

[英]Typescript: get keys from Map or object

假設我想編寫一個 function ,它從Map或普通 object 中返回密鑰作為普通數組,如下所示:

function keys <K>(m: Map<K, any> | { [key: string]: any }) {
  if (m instanceof Map) return Array.from(m.keys())
  return Object.keys(m)
}

如果我然后嘗試從普通的 object 中檢索密鑰,則可以正常工作:

let a = ((g: string[]) => g)(keys({})) // this works

但是,使用Map<number, number>會給我一個類型錯誤:

let a = ((g: number[]) => g)(keys(new Map<number, number>()))
// Argument of type 'number[] | string[]' is not assignable to parameter of type 'number[]'

let a = ((g: number[]) => g)(keys<number>(new Map<number, number>()))
// Even this produces the same error

let a = ((g: number[]) => g)(keys(new Map<number, number>()) as number[])
// This works but the cast kind of defeats the purpose

我錯過了什么? 我應該如何輸入這個以使 TypeScript 編譯器理解我的意思?

更新:

Function 簽名重載似乎是 go 的方式,這個版本工作正常:

function keys <K>(m: Map<K, any>): K[]
function keys (m: { [key: string]: any }): string[]
function keys (m: any): any {
  if (m instanceof Map) return Array.from(m.keys())
  return Object.keys(m)
}

檢查 typescript function 簽名重載: https://www.typescriptlang.org/docs/handbook/functions.html#overloads

您可以定義一組不同的簽名,因此您可以為object案例定義一個簽名,為Map案例定義一個簽名:

function keys <K>(m: Map<K, any>): K[]
function keys (m: { [key: string]: any }): string[]
function keys (m: any): any {
  if (m instanceof Map) return Array.from(m.keys())
  return Object.keys(m)
}

您可以將普通函數與 generics 一起使用:

function keys<K extends PropertyKey>(m: Map<K, any> | { [P in K]: any }): K[] {
    if (m instanceof Map) return Array.from(m.keys())
    return Object.keys(m) as K[]
}

let a = (g => g)(keys({})) // never[]
let a0 = (g => g)(keys({foo: "bar"})) // "foo"[]
let a1 = (g => g)(keys(new Map<number, number>())) // number[]
let a2 = (g => g)(keys<number>(new Map<number, number>())) // number[]
let a3 = (g => g)(keys(new Map<1 | 2, number>())) // (1 | 2)[]

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM