绑定和返回函数中的“this”上下文中的打字稿错误

Posted

技术标签:

【中文标题】绑定和返回函数中的“this”上下文中的打字稿错误【英文标题】:Typescript error in `this` context in bound & returned function 【发布时间】:2021-04-25 17:14:48 【问题描述】:

我有一个函数URLBuilder,它作为一个模块工作(它返回一个包含各种函数的对象,并且这些函数与上下文对象很好地绑定,所以this 绑定按预期工作,我们可以访问@ 987654323@里面这些函数正确)

我的问题是为什么打字稿不理解URLBuilder 的返回对象内的函数this 绑定?即使我尝试手动添加返回类型,Typescript 也会抱怨 when using the URLBuilder 在没有 this 上下文的情况下无法接受该函数。

我们如何让 typescript 理解返回对象中这个绑定函数的this

我要解决的 Typescript 错误是:

The 'this' context of type 'URLBuilderAPI' is not assignable to method's 'this' of type 'ExecutionContext'.

interface URLBuilderOptions 
    baseURL: string,


interface ExecutionContext 
    options: URLBuilderOptions,
    predefinedValues:  protocol: string ,



/************************* */

function generateRequestURL(this: ExecutionContext, customOptions:  subRoute: string ) 

    return `$this.predefinedValues.protocol:$this.options.baseURL/api/v3/$customOptions.subRoute/some-url`;


/************************* */


function URLBuilder(options: URLBuilderOptions) 

    const predefinedValues = 
        protocol: 'https',
    

    const context = 
        options,
        predefinedValues,
    

    const API = 
        generateRequestURL: generateRequestURL.bind(context)
    

    return API;



/*********************** */

// 1st try

let urlInstance = URLBuilder( baseURL: 'www.url.com' );

urlInstance.generateRequestURL(); 
// typescript cannot understand function params and auto suggest them!

/*********************** */


interface URLBuilderAPI 
    generateRequestURL: typeof generateRequestURL,


function URLBuilder_WithReturnTypes(options: URLBuilderOptions): URLBuilderAPI 

    const predefinedValues = 
        protocol: 'https',
    

    const context = 
        options,
        predefinedValues,
    

    const API = 
        generateRequestURL: generateRequestURL.bind(context)
    

    return API;



/*********************** */

// 2nd try

let urlInstanceWithTypes = URLBuilder_WithReturnTypes( baseURL: 'www.url.com' );

urlInstanceWithTypes.generateRequestURL( subRoute: '/test/' )
/**
 * typescript error:
 * The 'this' context of type 'URLBuilderAPI' is not assignable to method's 'this' of type 'ExecutionContext'.
 */
/*********************** */

【问题讨论】:

第一个版本有什么问题?我在generateRequestURL 中看到了建议。你用strictBindCallApply吗?因为如果不是,则 bind 将返回 any 我没有用strictBindCallApply,我现在测试一下 【参考方案1】:

如果您使用strictBindCallApply 编译器选项,则代码将按预期工作,并且您将在第一次尝试时获得完成 (Playground Link)。如果没有strictBindCallApplybind 将返回any,因此您将无法检查函数的参数(Playground Link)

如果您不想启用此选项,您可以对bind 的结果使用类型断言来获取具有相同参数和返回类型的类型,但删除this 的类型:

....
    const API = 
        generateRequestURL: generateRequestURL.bind(context) as OmitThisParameter<typeof generateRequestURL>
    
...

Playground Link

你也可以定义你的接口来省略this参数:


interface URLBuilderAPI 
    generateRequestURL: OmitThisParameter<typeof generateRequestURL>,


Playground Link

【讨论】:

它有效,谢谢。只是想知道是否存在其他选项...我们可以创建一个可以在函数外部定义的接口类型并将其用作函数的返回类型吗? @LouayAlosh 添加了一个带有接口的版本并使用了OmitThisParameter,而不是使用ParametersReturnType

以上是关于绑定和返回函数中的“this”上下文中的打字稿错误的主要内容,如果未能解决你的问题,请参考以下文章

类中的打字稿外部回调绑定

猫鼬模式预方法中的打字稿错误:“this”意外别名为局部变量

当“@”用于打字稿类组件模板中的事件绑定时,Vetur 未正确读取函数名称

打字稿自定义装饰器:this的上下文

打字稿中的方法返回类型为null

打字稿中的Nodejs需要('this')(that)