gpt4 book ai didi

TypeScript - 检查对象的属性是否是具有给定签名的函数

转载 作者:搜寻专家 更新时间:2023-10-30 21:22:12 24 4
gpt4 key购买 nike

我有一个从对象获取属性的函数。

// Utils.ts
export function getProperty<T, K extends keyof T>(obj: T, key: string): T[K] {
if (key in obj) { return obj[key as K]; }
throw new Error(`Invalid object member "${key}"`);
}

我想检查返回的属性是否是具有给定签名的函数,然后使用提供的参数调用该属性。

getProperty() 用于动态获取对象的方法之一并调用它。我试过:

let property: this[keyof this] = utils.getProperty(this, name);
if (typeof property === 'function') ) { property(conf); }

但这会给出“无法调用类型缺少调用签名的表达式。类型‘any’没有兼容的调用签名。”错误。我知道来自 getProperty() 的属性确实可以是任何类型,但是如何确定它是带有 (conf: {}): void 签名的函数?

最佳答案

它看起来不像typeof type guards函数类型存在。这似乎是设计使然;见microsoft/TypeScript#2072 (这个问题是关于 instanceof 类型保护的,但我猜这是类似的推理)。

但是,TypeScript 确实有 user-defined type guards ,这意味着您可以编写一个函数,以任何您喜欢的方式缩小其参数的类型。


TypeScript 的静态类型系统是 erased当代码被编译成 JavaScript 时。在运行时,没有诸如 (conf: {}) => void 之类的东西可供您检查。如果您想编写一个运行时测试来区分 (conf: {}) => void 类型的值与其他类型的值,您将只能做到这一点。

您可以测试是否 typeof x === "function"。但这只是告诉你这是一个功能。它指示函数采用多少个参数以及它们的类型。您还可以检查 x.length === 1 以查看该函数是否需要一个参数,尽管关于 Function.length 有一些警告。涉及剩余参数和默认参数。但现在你有点卡住了。

在运行时,任何关于函数参数类型的信息都将被删除,如果这些函数最初来自 TypeScript 代码的话。您最多可以通过使用一些测试参数调用它并检查是否出现问题来“探测”该函数。但这是一种具有可能副作用的破坏性测试,并且违背了在调用函数之前检查函数类型是否正确的目的。


也许您对这个限制没有意见,并且会假设 length1 的函数是一个足够好的测试。或者您可能有一些其他测试(例如,也许您可​​以将一个名为 isOfRightType 的属性添加到您关心的所有此类函数中,其值为 true,然后只测试它属性。这通过引入假阴性的可能性来消除假阳性)。一旦知道了运行时测试,就可以制作类型保护:

function isFunctionOfRightType(x: any): x is (conf: {})=>void {
return (typeof x === 'function') && (x.length === 1); // or whatever test
}

// ... later

let property: this[keyof this] = utils.getProperty(this, name);
if (isFunctionOfRightType(property)) { property(conf); } // no error now

Playground link to code

关于TypeScript - 检查对象的属性是否是具有给定签名的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50371351/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com