我正在尝试在Typescript中键入一个深度对象分解,我搜索了一大堆,但没有找到能完全回答我问题的内容,所以我想问一下。
我班上有类似 的东西:
public Example(
key1: string,
key2: string,
val: string,
callback: (list: string[]) => void
): void
{
chrome.storage.sync.get(
({
[key1]: list1,
[key2]: list2
}) => {
list1.includes(val)
? callback(list1.filter(i => i !== val))
: callback(list2)
}
);
}
我还没有找到键入list1
和list2
(如string[]
的方法,它们被设置为any
的方法,在尝试使用数组函数。我已经找到了一些示例,该示例说明了如果 key 是已知的({ key }: { key: string[] }
)如何键入,但我的情况并非如此。由于LHS是非静态的,因此我也无法创建Type。
我的示例有所更改,但包含了解决我的问题所需的一切。
如果需要的话,chrome.d.ts
我说:
/**
* Gets one or more items from storage.
* @param callback Callback with storage items, or on failure (in which case runtime.lastError will be set).
* Parameter items: Object with items in their key-value mappings.
*/
get(callback: (items: { [key: string]: any }) => void): void;
我敢肯定这可能真的很简单,我什么都没发现。话虽这么说,这个问题可能使其他人将来更容易找到,因此如果解决,它将是双赢的。
感谢所有帮助。
编辑:我想我也在寻找返回的不是 just string[]
的情况。如果您有一堆都是不同类型的数据怎么办?
答案 0 :(得分:1)
因此您将获得类型any
,因为get
函数具有这样的功能。
因此,您可以这样做:
type MyGet = (callback: (items: {[key: string]: string[]}) => void) => void
// inside the Example method
(chrome.storage.sync.get as MyGet)(
({
[key1]: list1,
[key2]: list2
}) => {
list1.includes(val)
? callback(list1.filter(i => i != val))
: callback(list2)
}
);
在可能遇到其他类型的情况下,另一种更好的方法是使用类型保护:
chrome.storage.sync.get(
({
[key1]: list1,
[key2]: list2
}) => {
if(Array.isArray(list1)) {
list1.includes(val)
? callback(list1.filter(i => i != val))
: callback(list2)
}
}
);
就类型安全而言,这是可以的,因为将类型any
缩小为string[]
应该被认为是可以的。
答案 1 :(得分:1)
使用declaration merging来更正第三方类型:
chrome.d.ts
import {} from 'chrome';
declare namespace chrome.storage {
export interface StorageArea {
get(callback: (items: { [key: string]: string[] }) => void): void;
}
}
如果您想知道,将文件顶部的空白import语句要求将其视为模块增强而不是其定义。
最好的事情是什么?如果您对此处的string[]
不满意,则可以通过其他方式对其进行扩充。您还可以将get
设为通用。