接口的额外属性作为同一接口方法的参数类型

问题描述 投票:0回答:1

我正在尝试引入一个 API,您可以在其中传递对象,并且该对象的方法将

this
键入为对象本身,而无需显式指定对象的类型。

我试过这个:

interface BaseProcessor<T> {
    process(this: Readonly<T>): void;
    [key: string | symbol]: unknown;
}

function makeProcessor<T extends BaseProcessor<T>>(definition: T) {
    // code...
}

export const processor = makeProcessor({
    hello: "world!",
    // other possible properties of different types...
    
    process() {
        console.log(this.hello); // <--- this.hello is of type "unknown"
    }
});

Typescript Playground 链接

我想要实现的是让

this.hello
成为
string
类型。同样,将添加到对象的其他属性将按照其值在
this
上键入,但稍微更改类型(例如,像提供的示例中那样将它们设置为只读)。

有可能做到这一点吗?任何帮助或建议表示赞赏。

typescript generics types
1个回答
0
投票

由于您正在寻找编译器在您的 this 方法中

infer
Readonly<T>
成为
process()
,因此使用 magical/intrinsic
ThisType<T>
实用程序类型
将有更好的成功机会,这是标记上下文
this
类型的一种方式。那么你不需要
BaseProcessor
成为 generic:

interface BaseProcessor {
    process(): void;
    [key: string | symbol]: unknown;
}

你只需要

makeProcessor()
以一种能够正确地让
ThisType
发痒的方式变得通用即可:

function makeProcessor<T extends BaseProcessor>(
    definition: T & ThisType<Readonly<T>>
) {
    // code...
}

现在你得到了预期的行为:

const processor = makeProcessor({
    hello: "world!",

    process() {
        this;
        // ^? this: Readonly<{ hello: string; process(): void; }>
        console.log(this.hello);
    }
});

Playground 代码链接

© www.soinside.com 2019 - 2024. All rights reserved.