与仅使用接口相比,此返回类型从不做什么?

2024-06-02

在尝试用 Typescript 创建工厂时,我遇到了本文 https://medium.com/codex/factory-pattern-type-script-implementation-with-type-map-ea422f38862我对这部分感到困惑:

  class UserFactory {
  static getUser(k: Keys) : ExtractInstanceType<userTypes> {
    return new userMap[k]();
  }

可供参考的类型定义:

type ExtractInstanceType<T> = T extends new () => infer R ? R : never;

我不知道为什么我们需要提取实例类型为什么我们不想只使用 IStaff:

  class UserFactory {
  static getUser(k: Keys) : IStaff {
    return new userMap[k]();
  }

我也对 Keys 在这里所说的感到困惑,我认为这只是 userMap 可以保存的字典中的键之一,这将是一个字符串?

但是,当使用该方法时,它是否与对象实例一起用作其参数,还是不可能?

const manager = new Manager();
const anotherManger = UserFactory.getUser(manager);

我不确定为什么我们需要 ExtractInstanceType 以及为什么我们不想只使用 IStaff?

因为整个要点userMap关联的静态方法是将名称映射到具体的,具体的类,而不是它们实现的接口。如果这些类中的任何一个在通用 IStaff 接口之上实现了特定于类的内容(而且几乎肯定会),那么您的代码将充斥着instanceof或每次调用不在其中的方法时进行其他检查IStaff如果您没有通过使用该静态方法缩小类型来满足编译器的要求,从而将其消灭在萌芽状态。

我以为这只是 userMap 可以保存的字典中的键之一,这将是一个字符串?

正如我在对您的回答的评论中所建议的其他问题 https://stackoverflow.com/questions/69690959/creating-a-factory-in-typescript-using-infer-and-typeof我认为问题在于你仍然混为一谈types and values。 TBF 存在一些重叠并没有帮助。

考虑字符串“a”。在 Typescript 中,有value'a' 但也有文字类型 'a',它是类型的子集string:

type a = 'a'
let a: a = 'a'
let s: string = a // note, variable a not string literal a!
const foo = {
  a: 1
}

console.log(foo[a]) // 1
console.log(foo[s]) // type error!

// ok, let's try the string literal 'a'
s = 'a'
console.log(foo[s]) // same type error!
// eff

Since a字面上是“a”,我们可以索引foo用它。但s是一个到字符串的可变绑定,并且你不能索引foo即使我们设置了任何旧字符串value到“a”,即使我们将其设置为variable a其中有type a, s is still a string编译器无法保证我们不会重新分配非 a 值。操场 https://www.typescriptlang.org/play?#code/C4TwDgpgBAhlC8UDkMkCgA2FiwFywWVU2ygGd8zgAnASwDsBzQmNAYwHt6qoAzDjoQDeaKHigBGNAF807LmQ5YAdBg6MAFPw4BtGAF0AlPO5KIq9VoE6yRtEA

类型可能看起来像值,并且在某些上下文中可能具有完全相同的值外貌作为价值观,但它们是not值,也不是值类型。继续往右走...

对于对象字面量,我们在编译时知道对象中的键,因此如果我们有一个 foo 对象{a: 'hi', b: 5} then keyof typeof foo is 'a' | 'b'。注意:这些是字符串,但在本例中它们是types,不是 JavaScriptvalues。博客文章中的方法限制了k参数只能传递为编译时已知键中的值userMap.

但是,当使用该方法时,它是否与对象实例一起用作其参数,还是不可能?

哦,这是possible改变方法以这种方式工作,这是毫无意义的。如果您有一个实例的引用,那么您已经有一个对其构造函数的引用,您不需要查找表来创建另一个实例:

class Foo {}

const foo = new Foo()
const bar = new (foo.constructor as any)()
bar instanceof Foo // true

再次强调一下重点userMap访问它的静态方法是为了让工厂能够通过以下方式查找正确的用户类字符串名称.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与仅使用接口相比,此返回类型从不做什么? 的相关文章

随机推荐

  • 删除对某个功能的支持的“最佳实践”是什么?

    我有一个处理多种消息格式的库 这些格式中的每一种都密切相关 它们是通用的基础 XML 然后每种格式都有一些额外的约束或额外的数据 创建其中一种格式只是为了支持概念验证或试点工作 试点已经结束 不再使用 并且施加了一些尴尬的限制 我已获得删除
  • 反向合并具有干净历史记录的缝合功能分支

    我有这个 d0 f1 d1 d2 f2 d3 merge d4 f3 merge
  • 如何在Android 4.2中更改Action Bar选项菜单的背景颜色?

    我想更改 Android 4 2 中选项 溢出 菜单的背景颜色 我已经尝试了所有方法 但它仍然显示主题设置的默认颜色 我使用了以下代码和 XML 配置 MainActivity java public class MainActivity
  • Intellij - 无法使用较新的 Java 8 类 - 错误:“API 的使用记录为 @since 1.6+..”

    我正在尝试使用java lang function Function在我的 java 8 代码库中 但我在 Intellij 中不断收到以下错误 API 的使用记录为 since 1 6 此检查发现所有 文档中带有 since 标记的方法的
  • 使用 CodeIgniter 加载视图文件夹外的视图

    我需要从以下范围之外加载视图 this gt load gt view 这似乎是从base application views目录 如何从外部访问视图 application 目录 我想我将不得不延长CI Loader class这是最好的
  • 使用 bootstrap 将并排的网格位置交换到顶部和底部

    我有两个 div 内容和图像 它们在中等屏幕中并排放置 col md 6 内容 col md 4 图片 因此 当屏幕尺寸更改为小屏幕和 xs 屏幕时 这些 div 不应该并排放置 它们应该像这样顶部和底部对齐 image content 这
  • 集合组查询是否需要{path=**}?

    我通读了集合组查询文档 https firebase google com docs firestore security rules query secure and query documents based on collection
  • 以编程方式更改 UISlider 的范围

    如何以编程方式设置 UISlider 的最小最大范围 例如 虚拟代码 UISlider slider UISlider alloc init slider min 3 slider max 3 EDIT 所以我有以下内容 sl minimu
  • UIPopOver 和方向改变

    在我的应用程序中 我有 3 个 UIPopOver 当用户点击工具栏中的按钮时 它们就会出现 如果弹出窗口已经打开 如 willAnimateRotationToInterfaceOrientation 当用户旋转 iPad 时 我需要使弹
  • PopupWindow onitemclick 中的 Android Listview 在某些设备上不起作用

    我的 ListView 在 PopupWindow 内 当我显示 PopupWindow 并单击设备 ASUS K00z 中的 Listview 行时 fonepad 工作得很好 但在 HTC Z715e 中不起作用 项目单击事件未触发 1
  • Mongoose 更新嵌入文档不起作用

    问候大家 我定义了一个深度嵌入的猫鼬模型 Person 其中包含一个字段 Contact Contact 有一个 Address 数组 用于这个人的工作 家庭 送货等地址 当我想要更新地址并使用模型的 保存 功能时 更改并未反映在数据库中
  • python log n 选择 k

    scipy misc comb 返回 n 选择 k 是使用 gammaln 函数实现的 是否有一个函数保留在日志空间中 我看到没有 scipy misc combln 或任何类似的 自己实现很简单 但如果它已经在某个包中 那就很方便了 我在
  • PUT/DELETE 与 REST 是自动幂等的吗?

    我正在学习 REST 和 PUT DELETE 我读到这两者 以及 GET 都是幂等的 这意味着多个请求使服务器进入相同的状态 重复的 PUT DELETE 请求是否会离开 Web 浏览器 当使用XMLHttpRequest 换句话说 服务
  • 包管理器已去世

    我收到一位安装了很多应用程序的用户发来的邮件 称当我的应用程序使用以下代码收集活动信息时 他遇到了问题 getPackageManager queryIntentActivities mAinIntent 0 完整来源在这里 https g
  • = 上的语法无效? [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我是 python 的初学者 试图使用 yes no 来制作一个非常简单的程序 它表示该行中的第一个 存在语法错误 if monk
  • 如何为 Python 2 安装 pip

    I run python version and get Python 2 7 3 I run pip version and get pip 1 5 from usr local lib python3 2 dist packages p
  • 使用 gv$session 判断查询是否挂起

    我有一个在 Oracle 中运行的查询 该查询可能会挂起 也可能不会挂起 它现在已经运行了大约 10 个小时 但根据我正在加载的数据量 这可能并非不合理 我正在查看 gv session 中的会话 想知道是否有一种方法可以转换该信息以查看是
  • 在内存有限的二叉树中查找第一个 null

    我有一个二叉树 其中每个节点都可以有一个值 我想找到树中值为空并且最接近根的节点 如果有两个节点到根的距离相同 则任意一个都可以 我需要最小化对二叉树的读取访问次数 假设工作内存仅限于 k 个节点 深度 k 的 DFS 是详尽的 但除非我首
  • 如何将引用分配给多个组件

    我正在使用 React 来渲染多个数据array map 如何禁用列表中单击的按钮 这是我的代码 onRunClick act e this refs btn setAttribute disabled true render return
  • 与仅使用接口相比,此返回类型从不做什么?

    在尝试用 Typescript 创建工厂时 我遇到了本文 https medium com codex factory pattern type script implementation with type map ea422f38862