在TypeScript中将符号用作对象键类型


20

由于MDN表示,我试图将符号定义为键类型的对象:

符号值可以用作对象属性的标识符[...]

但是使用它作为键属性的类型:

type obj = {
    [key: symbol | string]: string
}

导致以下错误:

TS1023:索引签名参数类型必须为“字符串”或“数字”。

即使它可以用作索引类型。我正在使用最新的打字稿版本(v3.7.2),发现了相关的问题:

我也看过打字稿符号文档,但它们仅显示了它如何用作值,而不是类型。

例:

const obj = {} as {
    [key: number | symbol]: string // Won't work
};

const sym = Symbol('My symbol');
obj[sym] = 'Hi';

关于Microsoft / TypeScript的问题

开启功能要求


我认为TypeScript在其对象类型声明中仅支持特定的符号。难道你真的想要的任何 symbol?也许显示一个示例您想如何使用您的type obj-我怀疑所有符号键属性都将是strings。
Bergi

@Bergi我添加了一个示例,也许我已经监督了一些事情,但是我找不到让ts接受符号的方法(不使用any它是一种不好的做法)。
西蒙


不确定是否正确,但是您是否尝试使用Map<Symbol,String>我们拥有的Map,是否可以达到您想要实现的目的
pavan kumar

对我来说,同样的问题,我想令人讨厌的部分是关于“ TS是JS的超集”的虚假广告-嗯,不完全是。这是一个完美的例子。
Patrick

Answers:


3

不幸的是,目前在TypeScript中这是不可能的。如果您必须与某些期望使用此API的API进行互操作,或者真的要使用符号作为键,则可以使用以下笨拙的版本:

// Ensure we can not pass regular map to our custom functions
type SymbolMapTag = { readonly symbol: unique symbol }

type SymbolMap = SymbolMapTag & {
    [Key in string | number | symbol]: string;
}

function set_symbol<T extends SymbolMap, TSym extends symbol>
(target: T, sym: TSym, value: T[TSym]) {
    target[sym] = value;
}

function get_symbol<T extends SymbolMap, TSym extends symbol>
(target: T, sym: TSym): T[TSym] {
    return target[sym];
}

const symbol_map = {} as SymbolMap;

const sym = Symbol('My symbol');
set_symbol(symbol_map, sym, "hi");
get_symbol(symbol_map, sym); // string


type NonSymbolMap = {
    [Key in string | number]: string;
}

const non_symbol_map = {} as NonSymbolMap;
set_symbol(non_symbol_map, sym, "hi"); // error
get_symbol(non_symbol_map, sym); // error
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.