Typescript:传递类时如何检查类函数是否绑定

问题描述

我是一名打字手新手,我只是从docs了解--noImplicitThis编译标志,但是遇到了一个情况似乎并不以我自己的方式行事的案例会期望的,有人可以帮忙解释一下我如何正确键入检查绑定函数

因此,使用与文档类似的示例;尽管执行正确(但跳过了类型检查),但以下代码仍给我一个类型错误

type Card = {
    suit: string;
    card: number;
}

class Deck {
    suits: string[];
    cards: number[];

    constructor() {
        this.suits = ["hearts","spades","clubs","diamonds"];
        this.cards = Array(52);
    }

    cardPicker(this: Deck): Card {
        const pickedCard: number = Math.floor(Math.random() * 52);
        const pickedSuit: number = Math.floor(pickedCard / 13);

        return { suit: this.suits[pickedSuit],card: pickedCard % 13 };
    }
}

// this Could be a function that takes a callback as an
// argument,i.e. onClick
function runner(f: (this: Deck) => Card) : Card {
    return f();
}

const deck: Deck = new Deck()
const pickedCard: Card = runner(deck.cardPicker.bind(deck));
console.log("card: " + pickedCard.card + " of " + pickedCard.suit);

我有两个相关的问题:

首先,使用上面的代码

f()中的runner遇到类型错误,尽管该函数this被正确绑定:

The 'this' context of type 'void' is not assignable to method's 'this' of type 'Deck'


第二,要使代码通过类型检查,我可以通过将runner函数更改为以下代码修改代码

function runner(f: () => Card) : Card {
    return f();
}

但是如果我要(意外地)取消绑定传递到runner函数

const pickedCard: Card = runner(deck.cardPicker);

当我真的想要一个代码时,我没有收到编译错误,因为代码现在无法正确执行。


打字稿是否有办法确保在传递类函数之前绑定它们?

解决方法

如果要捕获范围(包括 this ),可以使用箭头功能:

public cardPicker = () => {
    const pickedCard: number = Math.floor(Math.random() * 52);
    const pickedSuit: number = Math.floor(pickedCard / 13);

    return { suit: this.suits[pickedSuit],card: pickedCard % 13 };
}
[...]
const pickedCard: Card = runner(deck.cardPicker);

Playground link with the full code

谈到架构,我认为cardPicker可能是一个以套牌为参数的外部函数,测试起来会更容易。

第一个提示:避免使用幻数。

第二个提示:看一下template literals,您将可以编写:`card: ${pickedCard.card} of ${pickedCard.suit}`