【问题标题】:Typescript error in `this` context in bound & returned function绑定和返回函数中的“this”上下文中的打字稿错误
【发布时间】: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,我现在测试一下

标签: javascript typescript binding this


【解决方案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
猜你喜欢
  • 2021-12-18
  • 2012-09-27
  • 2018-01-05
  • 2019-02-03
  • 2015-06-12
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多