问题描述
我是一名打字手新手,我只是从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}`