如何将已知的接口属性与自定义索引签名结合起来?

2023-12-31

如何键入一个可以同时具有几个属性的对象声明的可选属性, e.g.:

{ 
    hello?: string, 
    moo?: boolean 
}

以及自定义属性(必须是函数),例如:

    [custom: string]: (v?: any) => boolean

这就是我想看到的,例如:

const myBasic: Example = {moo: false}
// -> ✅ Valid! Using known keys

const myValid: Example = {hello: 'world', customYo: () => true}
// -> ✅ Valid! "customYo" is a function returning a bool. Good job!

const myInvalid: Example = {hello: 'world', customYo: 'yo!'}
// -> ☠️ Invalid! "customYo" must be a function returning a boolean

尝试将索引签名添加到具有已知密钥的接口(即hello?: string, moo?: boolean)要求所有键都是索引签名类型的子集(在这种情况下,函数返回boolean)。这显然失败了。


业主接受的问题(到目前为止)是不正确的。

您可以这样做:

您需要使索引签名成为接口中可以包含的所有类型的联合类型:

interface IExample {
    hello?: string;
    moo?: boolean;
    [custom: string]: string | boolean | YourFunctionType;
}

interface YourFunctionType {
    (v?: any): boolean;
}

请注意,我已将您的函数类型提取到一个单独的界面中以提高可读性。

影响:

这意味着 TS 很好地支持显式定义的属性:

const test: IExample = <IExample>{};
test.hello.slice(2); // using a string method on a string --> OK
const isHello = test.hello === true; // ERROR (as expected): === cannot be applied to types string and boolean
const isMoo2 = test.moo === true; // OK

然而,现在需要使用类型保护来检查索引签名中的所有属性,这会增加一点运行时开销:

test.callSomething(); // ERROR: type 'string | boolean | YourFunctionType' has no compatible call signatures
if (typeof test.callSomething === 'function') { // alternatively you can use a user defined type guard, like Lodash's _.isFunction() which looks a little bit nicer
    test.callSomething(); // OK
}

另一方面:运行时开销是必要的,因为它可能是test是这样访问的:

const propertyName: string = 'moo';
test[propertyName](); // ERROR: resolves to a boolean at runtime, not a function ...

// ... so to be sure that an arbitrary propertyName can really be called we need to check:
const propertyName2: string = 'arbitraryPropertyName';
const maybeFunction = test[propertyName2];
if (typeof maybeFunction === 'function') {
    maybeFunction(); // OK
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将已知的接口属性与自定义索引签名结合起来? 的相关文章

随机推荐

  • Web api 和 Web api 2 之间的 PushStreamContent 有什么不同?

    我创建了两个相同的 Web api 项目 一个在 VS 2012 中 另一个在 VS 2013 中 两者都针对 4 5 net 框架 这些项目基于 Filip W 的视频下载教程 http www strathweb com 2013 01
  • 获取 MongoDB 中更新的文档

    我需要得到 id更新文档的 Mongo ObjectID 为此 我想获取更新的文档 我怎么才能得到它 我试过这个 collection update oldData newData function err doc console log
  • 如何获取Google云存储的授权令牌

    我正在尝试集成 Google 云存储 API 以将我所有的网络应用程序上传传输到 google 云存储 根据文档 我每次发出新请求时都需要传递授权标头 但无法在哪里获取授权令牌 我非常努力地检查了很多 Git 存储库和 StackOverf
  • 从货币代码获取 CultureInfo?

    我需要获取不同货币代码的 System Globalization CultureInfo 示例 欧元 英镑 美元 目前 我正在基于这 3 个字母货币代码的 switch 语句中执行以下操作 显然这不是执行此操作的方法 var ci new
  • Rails:我如何需要 ActiveSupport 的救援_from 方法?

    我有这个代码application controller Method to capture and handle all exceptions rescue from Exception do ex Rails logger debug
  • 如何获取 Windows 应用商店应用程序中正在执行的程序集版本信息?

    在将应用程序移植到 Windows 应用商店时 我注意到 NETCore Framework 不包括 System Reflection Assembly GetExecutingAssembly 我用它来获取版本信息以显示在菜单屏幕上 是
  • Rails 3.1、资产管道和 IE 6 & 7 处于生产模式 - 某些 CSS 和 js 未正确加载

    在生产模式下尝试我的 Rails 3 1 应用程序 Debian 6 Ruby 1 9 2 Passenger 我使用 IE 6 和 IE 7 进行了尝试 但某些资源未正确加载 在开发模式下一切正常 一些 css 和 js 未正确加载 所有
  • 如何在 Ruby 中的哈希列表中提取每个键的更大值

    我可以想象有一种简单的方法可以做到这一点 而不是使用许多变量和状态 我只想获得哈希列表中每个键的最高值 例如 1 gt 19 4 1 gt 12 4 2 gt 29 4 3 gt 12 4 2 gt 39 4 2 gt 59 4 Resul
  • 无法打开文件“glew32.lib”

    我已经下载了 glew 1 9 0 zip 在 C glew 1 9 0 build vc6 和 C glew 1 9 0 build vc10 下构建了项目 并且在将 Visual Studio 的路径设置为后无法构建glew inclu
  • Java字节码解释器

    我知道java程序首先被编译并生成与平台无关的字节码 但我的问题是 为什么这个字节码在下一阶段被解释而不是被编译 即使编译通常比解释更快 你是在自问自答 字节码是平台无关的 如果执行编译后的代码 则它不会在每个操作系统上运行 这就是 C 的
  • 警报对话框背景主题/颜色

    我想设置AlertDialogue主题或change背景颜色 虽然我知道它有一个默认主题 但在不同的版本中我得到了不同的主题 所以我想为所有版本修复它 或者简单地将背景颜色更改为白色 NonNull public Dialog onCrea
  • 从 PlaceAutocompleteFragment android (Google Places API) 获取国家/地区代码

    在 Android 版 Google Places API 中 我使用 PlaceAutocompleteFragment 来显示城市 国家 这里正在获取地址 名称 placeId 等 Place对象仅包含这些字段 Override pub
  • 如何使用系统签名密钥对我的应用程序进行签名?

    我需要创建一个 Robotium 应用程序 该应用程序将使用 设置 应用程序从菜单 设置 gt 无线和网络 gt Wi Fi 打开 关闭 WIFI 我设法找到了一些示例代码here http code google com p roboti
  • 如何缩放 SVG 路径

    我尝试缩放 svg 路径之类的元素 但缩放对于 div 元素工作正常 不适用于 svg 路径元素 我在下面附上了我的代码 有什么建议吗
  • ngModel 自定义 ValuesAccessor

    关于 ngModel 和 DI 的高级问题 正如我在这里看到的 https github com angular angular blob 2 0 0 beta 1 modules angular2 src common forms dir
  • R:按名称组合嵌套列表元素

    假设我有一个列表结构 其中有data frames嵌套在每个元素中 l lt list A list D data frame V1 seq 3 V2 LETTERS 1 3 E data frame V1 seq 3 V2 LETTERS
  • 如何在 Forth 中创建数组?

    我知道 这个问题过去经常被问到 也许之前的 Stack Overflow 帖子中已经给出了这些信息 但学习 Forth 是一项非常复杂的任务 重复有助于理解串联编程语言相对于 C 等替代语言的优势 我从 Forth 教程中学到的是 Fort
  • 基于内容的节流

    我想知道Camel是否可以根据交换的内容进行限制 情况如下 我必须通过soap 调用网络服务 其中 发送到该webservice的参数中有一个customerId 问题是 如果给定的 customerId 每分钟有超过 1 个请求 则 We
  • jQuery keyup keyCode 在 Opera 中不起作用

    Opera 浏览器是否有可能忽略 keyCode 40 向下箭头 test keyup function e body append e keyCode 测试它 http www jsfiddle net V9Euk 454 http ww
  • 如何将已知的接口属性与自定义索引签名结合起来?

    如何键入一个可以同时具有几个属性的对象声明的可选属性 e g hello string moo boolean 以及自定义属性 必须是函数 例如 custom string v any gt boolean 这就是我想看到的 例如 cons