我试图构建类型和回调的映射,所以我从如下 struct 开始:

type Instantiable<T = unknown> = new (...args: any[]) => T;
type SingleParamFn<TInput = unknown, TOuput = unknown> = (arg: TInput) => TOuput;

type TypesRecord<T> = { type: Instantiable<T>, callback: SingleParamFn<T> };
type TypesMap = TypesRecord[];   // This is the structure

例如:

const myMap: TypesMap = [{ type: Date, callback: (value) => 'this is a Date' }];

这似乎像预期的那样工作,但我意识到这有点低效,因为需要循环数组以找到所需的类型.

我开始try 将这些类型作为对象键,至少在Google Chrome中是这样的:

class MyFancyObject {}
class MyOtherObject {}

const map = {
   [Date]: () => 'this is a date',
   [MyFancyObject]: () => 'this is a fancy object',
   [MyOtherObject]: () => 'this is another object'
};

console.log(map[Date]());           // 'this is a date'
console.log(map[MyFancyObject]());  // 'this is a fancy object'
console.log(map[MyOtherObject]());  // 'this is another object'

const obj = new MyFancyObject();
console.log(map[obj.constructor]());           // 'this is a fancy object'
console.log(map[(new Date()).constructor]());  // 'this is a date'

我一直在判断一些文档,似乎一个对象的键只能是string or a Symbol,所以我判断了符号的组成,它似乎有点奇怪,因为它被定义为built-in object whose constructor returns a symbol primitive that's guaranteed to be unique,而对象的构造函数(据我所知)是唯一的.

考虑到所有这些,使用构造函数作为对象键是一种可靠的方法吗?如果是,如何定义此类对象的typescript类型?如果不是,是否还有其他选项(如Map对象)?

推荐答案

考虑到所有这些,使用构造函数作为对象键是一种可靠的方法吗?

不可以.正如您所说,对象的键只能是字符串或Symbols.符号是从Symbol上的属性(对于已知的、规范定义的符号)或通过调用Symbol()Symbol.for("...")获得的基元.构造函数不是符号,而是函数.

map对象的键是字符串.当您使用像[MyFancyObject]这样的计算(computed)属性名称时,如果您提供的值不是字符串或符号(在您的情况下,它是一个函数),它会隐式转换为字符串,就像您使用String(MyFancyObject)一样.您可以在这里看到:

class MyFancyObject {}
class MyOtherObject {}

const map = {
   [Date]: () => 'this is a date',
   [MyFancyObject]: () => 'this is a fancy object',
   [MyOtherObject]: () => 'this is another object'
};

console.log(Object.keys(map));
console.log(map[MyFancyObject]());            // "this is a fancy object"
console.log(map["class MyFancyObject {}"]()); // also "this is a fancy object"

正如你所看到的,你认为是MyFancyObject的键实际上是字符串"class MyFancyObject {}".

canMap中使用构造函数作为键,但:

class MyFancyObject {}
class MyOtherObject {}

const map = new Map([
   [Date, () => 'this is a date'],
   [MyFancyObject, () => 'this is a fancy object'],
   [MyOtherObject, () => 'this is another object'],
]);

console.log(map.get(MyFancyObject)());

在这种情况下,键实际上是构造函数,而不是从它们派生的字符串.

Javascript相关问答推荐

materialized - activeIndex返回-1

Bootstrap动态选项卡在切换选项卡后保持活动状态,导致元素堆叠

为什么我的includes声明需要整个字符串?

如何在Connect 4游戏中 for each 玩家使用位板寻找7形状?

如何使用JavaScript将文本插入空div

Webpack在导入前混淆文件名

Reaction组件在本应被设置隐藏时仍显示

变量在导入到Vite中的另一个js文件时成为常量.

无法避免UV:flat的插值:非法使用保留字"

按什么顺序接收`storage`事件?

TabNavigator和StackNavigator之间的Reaction Native中的导航问题

在对象的嵌套数组中添加两个属性

将字符串解释为数字;将其重新编码为另一个基数

REACT-本机错误:错误类型错误:无法读取未定义的容器的属性

MAT-TREE更多文本边框对齐问题

与find()方法一起使用时,Mongoose中的$or运算符没有提供所有必需的数据

Node.js的Fetch()调用总是创建新的Express会话

打字脚本中的函数包装键入

如何让noWrap在嵌套在Alert/AlertTitle组件中的排版组件中工作?

为什么我找不到东西?