首先,你可以使用特殊的this范围 https://www.typescriptlang.org/docs/handbook/2/classes.html#this-parameters语法来识别您期望的对象类型this
to be:
function foo (this: {bar: string}) {
return this.bar; // no more error
}
如果您直接调用它,这会有所帮助:
foo(); // error, this is undefined, not {bar: string}
var barHaver = { bar: "hello", doFoo: foo };
barHaver.doFoo(); // acceptable, since barHaver.bar is a string
var carHaver = { car: "hello", doFoo: foo };
carHaver.doFoo(); // unacceptable, carHaver.bar is undefined
TS3.2+ 更新
TypeScript 3.2 推出the --strictBindCallApply编译器选项 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#strictbindcallapply它强类型化了函数的 .call() 方法。如果你使用这个(或the --strict编译器功能套件 https://www.typescriptlang.org/tsconfig/#strict其中包括这个),那么this
参数也将强制执行foo.call()
按预期行事:
foo.call({ bar: "baz" }); // okay
foo.call({ baz: "quux" }); // error!
TS3.2 之前的答案如下:
但你想用foo.call()
。不幸的是Function.prototype.call()
输入 TypeScript 并不会真正为您强制执行此限制:
foo.call({ bar: "baz" }); // okay, but
foo.call({ baz: "quux" }); // no error, too bad!
将更好的东西合并到 TypeScript 中Function
声明给我带来了问题,(第一点丑陋;你需要强制转换foo
到某事)所以你可以尝试这样的事情:
interface ThisFunction<T extends {} = {}, R extends any = any, A extends any = any> {
(this: T, ...args: A[]): R;
call(thisArg: T, ...args: A[]): R;
}
A ThisFunction<T,R,A>
是一个函数this
类型的T
,类型的返回值R
,以及类型的剩余参数A[]
。 (丑陋的第二点:您无法轻松地以类型系统强制执行的方式指定不同类型的多个参数。)
然后您可以投射foo
to ThisFunction<{ bar: string }, string>
,(丑陋的第三点:类型系统不会推断this
类型),然后最后使用call()
:
(<ThisFunction<{ bar: string }, string>>foo).call({ bar: "baz" }); // okay, and
(<ThisFunction<{ bar: string }, string>>foo).call({ baz: "quux" }); // error, hooray!