-1

我是一个打字稿新手,我只是从文档--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()在函数中收到类型错误:runnerthis

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);

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


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

4

1 回答 1

0

如果要捕获范围(包括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);

带有完整代码的游乐场链接

说到架构,我认为cardPicker可以是一个以deck作为参数的外部函数,它会更容易测试。

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

第二个提示:看看模板文字,您将能够编写:`card: ${pickedCard.card} of ${pickedCard.suit}`

于 2020-10-17T19:28:59.167 回答