繁体   English   中英

打字稿函数/对象参数

[英]Typescript Function/Object parameters

为什么打字稿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允许回调作为对象类型。

如何确保这会导致错误?

与打字稿条件句 (TS V2.8),我们可以使用Exclude排除Functionsobject使用类型Exclude<T, Function>

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>{}

正如您在下图中所看到的,前两次调用find会抛出错误,而不是后两次调用find

TypeScript排除

然后显示的错误如下:

  • [ts]类型'(a,b)=> void'的参数不能分配给'never'类型的参数。 [2345]
  • [ts]类型'“我是一个字符串”'的参数不能分配给'object'类型的参数。 [2345]

对象和功能基本上是相同的,但是打字有助于我们消除它们的功能之间的歧义。

考虑一下:

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 = {}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM