没有显式声明类型的打字稿自动泛型类型 [英] Typescript automatic generic type without explicitly declare the type

查看:37
本文介绍了没有显式声明类型的打字稿自动泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个具有两个功能的接口.一个函数返回一个值.我想在同一接口的另一个函数中使用值的类型.我确实使用了泛型,但每次创建新对象时都必须明确声明类型.但没有它也可以做到.例如:

If I have an interface with two functions. one function returns a value. I want to use the type of value in another function in the same interface. I did use generics but I have to explicitly declare the type every time I create new object. but It could be done without it. For example:

interface myObject<T> {
    create(): T
    update(value: T): void // use value type defined in create method
}

这里我们使用上面的接口定义新对象:

and here we define new object using the interface above:

let test: myObject<string> = {
    create() {
        return "Hello"
    },
    update(value) {
        // do something with value
    },
}

可以在没有 的情况下编写 myObject.因为值类型已经在 create 方法中定义了吗?

It's possible to write myObject without <string>. as the value type already been defined in create method?

推荐答案

初步命名约定注意:标准做法是以大写字符开头的非原始类型名称,以将它们与变量/属性名称或原始类型区分开来.因此,我将在此答案中使用 MyObject 而不是 myObject:

Preliminary naming convention note: it is standard practice to start non-primitive type names with an uppercase character, to distinguish them from variable/property names or primitive types. So instead of myObject I will use MyObject in this answer:

interface MyObject<T> {
    create(): T
    update(value: T): void
}

--

您希望编译器为泛型类型参数T推断string.唯一发生这种泛型类型参数推断的地方是当你调用一个泛型函数,所以如果你想要这个行为,你需要从类型注释(const test: MyObject = ...)重构到调用一个辅助函数(consttest = toMyObject(...)).

You would like the compiler to infer string for the generic type parameter T. The only place such generic type parameter inference occurs is when you call a generic function, so if you want this behavior you will need to refactor from a type annotation (const test: MyObject<string> = ...) to calling a helper function (const test = toMyObject(...)).

此外,您希望编译器推断 update 方法的 value 回调参数的类型.这种类型的推理称为上下文输入.

Furthermore, you want the compiler to infer the type of the value callback parameter of the update method. This type of inference is called contextual typing.

不幸的是,当回调参数的上下文类型推断和泛型类型参数推断都依赖于同一个对象时,它们不能很好地协同工作.这是 TypeScript 的设计限制.有关详细信息,请参阅 microsoft/TypeScript#38872.

Unfortunately, contextual type inference of callback parameters and generic type parameter inference do not play well together when both depend on the same object. This is a design limitation of TypeScript. See microsoft/TypeScript#38872 for more information.

为了同时获得上下文类型推断和泛型类型参数推断,你的辅助函数需要将输入对象分成两部分:一个用于 create 以便泛型类型参数 T 可以推断,另一个用于 update 以便推断回调参数 value 的类型.

In order to get both contextual type inference and generic type parameter inference then, your helper function will need to split the input object into two pieces: one for create so that the generic type parameter T can be inferred, and the other for update so that the callback parameter value's type can be inferred.

这给了我们:

const toMyObject = <T,>(
    create: () => T,
    update: (value: T) => void
): MyObject<T> => ({ create, update });


让我们测试一下:


Let's test it:

let test = toMyObject(
    () => { return "Hello" },
    (value) => { console.log(value.toUpperCase()); }
);
// let test: MyObject<string>

看起来不错.编译器根据需要推断 test 属于 MyObject 类型,并且回调参数 value 也推断为 string(事实证明,您可以在 --strict 模式下无误地调用 value.toUpperCase()).

Looks good. The compiler infers that test is of type MyObject<string> as desired, and the callback parameter value is also inferred as string (as evidenced by the fact that you can call value.toUpperCase() without error in --strict mode).

Playground 代码链接

这篇关于没有显式声明类型的打字稿自动泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆