[英]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.