【问题标题】:how to use Twit's Typescript definitions; Callback function not assignable如何使用 Twit 的 Typescript 定义;回调函数不可分配
【发布时间】:2020-09-18 23:03:27
【问题描述】:

我刚刚开始接触 Node 和 typescript。我是一位经验丰富的 Java 工程师,做过前端工作,但主要是复制粘贴修改,没有完全理解所有的 javascript。现在我正在尝试更深入地了解 Node、JS 和 Typescript,并认为我在不了解所有情况的情况下跳得太远了。这只是一个小的个人项目。我想使用类并且喜欢 TS 提供的东西,但它似乎引入了比它解决的更多的复杂性和问题,所以也许不值得。

我正在尝试使用 Twit 包来阅读推文。在尝试将其转换为 TS 之前,它是否在普通 js 中运行良好。这是我的工作 js:

var _ = require('lodash');

var Twit = require('twit');

var T = new Twit({
    consumer_key:         '..'
  , consumer_secret:      '..'
  , access_token:         '..'
  , access_token_secret:  '..'
})

var options = { screen_name: 'TwitterUser',
                count: 200 };

T.get('statuses/user_timeline', options , function(err, data) {
  // it comes latest first; I want earliest first
  data.reverse();
  console.log(data[0]);

  // try to filter out alerts only
  var alerts = _.filter(data, function(tweet){
    return (tweet.text.indexOf('#alert') > -1) ||
          (tweet.text.indexOf('#ALERT') > -1);
  });

  for (var i = 0; i < alerts.length ; i++) {
    console.log(alerts[i].created_at + '  ' + alerts[i].text);
  }
})

这是 Typescript 版本:

import { IncomingMessage } from "http";
import _ from "lodash";
import Twit from "twit";

export class TwitterListener {

    getlatestTweets() {
        const T = new Twit({
            consumer_key:         '..'
          , consumer_secret:      '..'
          , access_token:         '..'
          , access_token_secret:  '..'
        })

        const options = { screen_name: 'TwitterUser',
                count: 200 };

        T.get('statuses/user_timeline', options, function(err, result: Response, data: IncomingMessage) {
            // it comes latest first; I want earliest first
            data.reverse();
            console.log(data[0]);
            
            // try to filter out alerts only
            const alerts = _.filter(data, function(tweet: Twit.Twitter.Status) {
                return (tweet.text.indexOf('#alert') > -1) ||
                    (tweet.text.indexOf('#ALERT') > -1);
            });
            
            for (let i = 0; i < alerts.length ; i++) {
                console.log(alerts[i].created_at + '  ' + alerts[i].text);
            }
        })
    }
}

最大的问题在于获取用户时间线的回调。 VS Code linter 说“类型参数(无论我尝试过什么)都不能分配给回调类型的参数。 DefinitelyTyped 的类型文档说这应该是这样的回调:

export interface Callback {
    (err: Error, result: Response, response: IncomingMessage): void;
}

这就是我尝试将其更改为的原因。我从简单的 js 版本中想到,其中回调是 function(err, data) 并且数据是一组推文/状态,它可能类似于 function(err:Error, data: any[])function(err, data: Array&lt;Twit.Twitter.Status&gt;),我也尝试过,但得到了同样的错误。我感觉这是我定义这个回调函数的语法,但不知道是什么。

我不明白回调定义如何从 function(err, data) 到带有结果和响应的回调类型。我错过了什么?

【问题讨论】:

  • 错误是Response 类型不同,它们只是名称相同。请注意,显式指定回调参数类型是一种不好的做法。应推断回调参数类型的正确性。
  • @AluanHaddad 感谢您的回复;您说“明确指定回调参数类型是一种不好的做法”;我很困惑,我认为强类型是 Typescript 的要点之一?按照您的建议推断出的回调参数类型应该如何?
  • 强类型是重点。指定编译器已知的类型不会增加类型的强度。 [1, 2, 3].map(x =&gt; x + x) 在 TypeScript 中是强类型的。所有类型都是已知的并经过验证。 [1, 2, 3].map((x: number) =&gt; x + x) 不会增加类型的强度。但是,在许多情况下,指定参数的类型可以减少类型信息,因为指定的类型可能是子类型,而且关键的是,如果类型知道编译器您将抑制@987654332 @错误。

标签: javascript typescript


【解决方案1】:

这里的问题是 - 正如 Aluan Haddad 的评论中提到的 - 你的函数的第二个参数的类型与 Twit 包中指定的回调函数类型不兼容。

回调函数的类型是这样的:

export interface Callback {
    (err: Error, result: Response, response: IncomingMessage): void;
}

我认为你的困惑的根源是,这个定义中的 Response 类型不是指内置的 Response 类型,但是 Twit 包用这个覆盖(阴影)这个定义:

export type Response = object;

这种类型定义有点混乱,至少命名应该反映它是 Twitter 响应,而不是描述浏览器内置的 Fetch API response 的内置定义。

要解决您的问题,您必须从 Twit 包中导入此响应定义或通过“Twit.Response”引用它。将其导入到您自己的文件中,也会隐藏其中的内置定义,您可以参考 Twit 包的“响应”类型。

import Twit, {Response} from "twit"

我想说的是,您的函数的强类型参数不是问题,而是它们导致您质疑您的代码。如果没有您自己的函数中的类型,您就不会看到问题,而且 - 也许 - 永远不会看到存在误解。

【讨论】:

  • 谢谢!我从 Aluan Haddad 了解到这是错误的响应类型,但我什至不明白如何导入正确的响应类型。现在我的问题是如何获取实际的 twitter 数据,因为 Response 和 IncomingMessage 类型似乎不包含任何实际的 twitter 数据。 IncomingMessage 属性看起来像更基本的 http 东西,而 Response 只是一个普通的对象。我错过了什么?
  • 如果您查看链接的 DefinitlyTyped 文档,您会发现它就是这样工作的:IncomingMessage 是从“http”导入的,而 Response 只是一个重命名的“对象”类型。
【解决方案2】:

查看twit's documentation后,我意识到回调接受三(3)个参数err - an errordata - arrays of tweetsresponse - response object from twitter。 js 版本起作用的原因是由于 javascript 的松散类型。

【讨论】:

    猜你喜欢
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多