当前位置: 首页 > 知识库问答 >
问题:

TypeScript函数/对象参数

陆俊迈
2023-03-14

为什么打字稿ES6没有检测到对象不是函数?

find: (collection: string, query: object, sortQuery = {}, cb?: Function)  => {
    socketManager.call('find', collection, query, sortQuery, cb);
}

基于此函数,您会假设这将失败:

this._services._socket.methods.find('vendors', {type: 'repair'}, (errVen, resVen) => {}

因为没有sortQuery对象,而是回调函数。这并没有给我任何类型的错误,这意味着typescript允许回调作为对象类型。

如何确保这会导致错误?

共有2个答案

皇甫伟彦
2023-03-14

对象和函数基本上是一回事,但是类型帮助我们消除它们的功能之间的歧义。

考虑一下:

const foo1: { (): string } = () => "";

变量foo的类型为object,但该对象是可调用的。。。这是一个函数,确实可以调用它,但您不能在其上设置名为bar的属性。

foo1(); // This works
foo1.bar = 5; // This, not so much.

也可以这样考虑:

const foo2: { bar?: number; } = {};

变量foo上有一个名为bar的属性。可以设置该属性,但无法调用该对象,因为它的类型不是可调用的。

foo2.bar = 5; // This works
foo2(); // This, not so much.

所以,让我们看看你原来的打字方式:

sortQuery = {}

########################################################################################################它没有任何属性,它不可调用,它只是一个对象。

我们已经看到函数是一个对象,所以可以很好地为它指定函数。但是,您将无法调用它,因为它没有定义为可调用。

const sortQuery: {} = () => ""; // This works.
sortQuery(); // This, not so much.
sortQuery.bar = 5; // Nor this.

如果完全控制源代码,则解决此问题的一种方法是从多个参数移动到具有命名属性的单个参数:

const foo = (params: { collection: string, query: object, sortQuery: {}, cb?: Function }) => { };

foo({ collection: "", query: {}, sortQuery: {} }); // Fine
foo({ collection: "", query: {}, sortQuery: {}, cb: () => { } }); // Fine
foo({ collection: "", query: {}, cb: () => { } }); // Not Fine

这通过要求名称而不是依赖于函数调用中的位置来消除任何歧义。

池砚文
2023-03-14

使用TypeScript条件(TS v2.8),我们可以使用Exclude对象中排除函数

let v = {
  find: <T extends object>(collection: string, query: object, sortQuery: Exclude<T, Function>, cb?: (a: string, b: string) => void) => {
  }
}

// Invalid
v.find('vendors', { type: 'repair' }, (a, b) => { })
v.find('vendors', { type: 'repair' }, 'I am a string', (a, b) => { })

// Valid
v.find('vendors', { type: 'repair' }, { dir: -1 })
v.find('vendors', { type: 'repair' }, { dir: -1 }, (a, b) => { })

然后可以按如下方式设置默认参数值:

sortQuery: Exclude<T, Function> = <any>{}

如下图所示,前两个调用fine会引发错误,但后两个调用fine不会引发错误:

随后显示的错误如下所示:

  • [ts]类型为“(a,b)的参数=

 类似资料:
  • 我有以下课程布局: 我正在为服务创建一个单元测试,但我想将ServiceHelper用作一个“活动”类,但要模拟ServiceHelper中的构造函数参数。有没有办法通过Mockito实现这一点?

  • 主要内容:TypeScript,JavaScript,TypeScript 类型模板,TypeScript,JavaScript,TypeScript,JavaScript,鸭子类型(Duck Typing)对象是包含一组键值对的实例。 值可以是标量、函数、数组、对象等,如下实例: var object_name = { key1: "value1", // 标量 key2: "value", key3: function() { // 函数 }, key4:["content1", "cont

  • 问题内容: 有没有办法保留解构函数参数的名称?即,根对象的名称? 在ES5中,我可以这样做(使用继承作为隐喻来说明这一点): 我正在使用同一个对象来保存多个配置参数。某些参数由父类使用,而某些参数由子类使用。 有没有办法用ES6中的结构化函数参数来做到这一点? 还是我需要提取所有选项,以便可以将它们分别传递给? 问题答案: 我本人在太多地方都有“选项”论据。我会选择1行额外的代码。在此示例中不值得

  • TypeScript 函数 函数是一组一起执行一个任务的语句。 您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。 函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。 函数定义 函数就是包裹在花括号中的代码块,前面使用了关键词 function: 语法格式如下所示: 实例 TypeScr

  • 我想创建一个函数对象,它也有一些属性。例如,在JavaScript中,我将执行以下操作: 现在在TypeScript中,我可以将这种类型描述为: 然而,如果不需要石膏,我实际上不能建造它。如: 如果没有石膏,你将如何建造这个?

  • 我们已经知道,在 JavaScript 中,函数就是值。 JavaScript 中的每个值都有一种类型,那么函数是什么类型呢? 在 JavaScript 中,函数就是对象。 一个容易理解的方式是把函数想象成可被调用的“行为对象(action object)”。我们不仅可以调用它们,还能把它们当作对象来处理:增/删属性,按引用传递等。 属性 “name” 函数对象包含一些便于使用的属性。 比如,一个