为什么必须在TS函数类型中指定参数名称? [英] Why do I have to specify parameter names in a TS function type?

查看:748
本文介绍了为什么必须在TS函数类型中指定参数名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用打字稿编写一些功能,这是TS接受的功能:

I am using typescript to write some function and this is the one that TS accepts:

export const useSomething = <T>() => {
    const useStorage = <T>(key: string, initialData: T) : [T, (newData: T) => Promise<void>] => {
        const [data, setState] = useState<T>(initialData);
        const setData = async(newData: T) : Promise<void> => {
            await storage.setItem<T>(key, newData);
        };
        return [data, setData];
    }
};

但实际上,我想以这种方式编写useStorage的返回类型:

But inithially I wanted to write the return type of useStorage in this way:

[T, (T) => Promise<void>]

为什么TypeScript要我在T出现之前写下newData名称?

Why TypeScript wants me to write down the newData name before the T occurs?

推荐答案

我认为您可以期望得到的最接近标准答案的地方是GitHub问题 microsoft /TypeScript#3081 .情况的要点是:

I think the closest thing you can hope for to a canonical answer is in the GitHub issues microsoft/TypeScript#13152 and microsoft/TypeScript#3081. The gist of the situation is this:

在函数类型中支持参数名称可用作库中函数和方法的文档.函数类型(username: string, password: string) => void(arg0: string, arg1: string) => void是相同的类型,但是前者可能比后者更能帮助开发人员编写代码.因此,有意支持在函数类型中使用类型注释的参数名称,该文档记录在(越来越过时的) TypeScript规范,并在各地的图书馆中使用. 用一种语言维护者的话:

Supporting parameter names in function types is useful as documentation for functions and methods in libraries. A function type (username: string, password: string) => void is the same type as (arg0: string, arg1: string) => void, but the former probably helps developers write code more than the latter does. So support for type-annotated parameter names in function types is intended, documented in the (increasingly outdated) TypeScript spec, and used in libraries all over the place. In the words of one of the language maintainers:

我...相信它可以帮助编写文档.以我所拥有的能力使用过Haskell之后,我会说省略参数名称...对任何学习新库的人都无济于事.尽管有一些关于更简单的语法的说法,但是类型是人们唯一的文档形式,通常会使人们难以理解意图……

I ... believe that it helps with documentation. Having used Haskell in the capacity that I have, I will say that omitting parameter names ... doesn't help anybody when they're learning a new library. While there's something to be said about an easier syntax, types being the only form of documentation for people often makes it difficult to understand intent ...


此外,在TypeScript中支持命名值的类型批注的情况下,类型可以省略,它们将由编译器进行推断.未能推断出任何有用的内容将导致对any的推断.例如,在以下功能中:


Furthermore, where type annotations on named values are supported in TypeScript, the types can be omitted and they will be inferred by the compiler. Failure to infer anything useful results in inferences of any. For example, in the following function:

function f(x, y): void { }
type F = typeof f;
// type F = (x: any, y: any) => void

xy的类型被推断为any(并且--noImplicitAny

the type of x and y is inferred as any (and you get a nice error with the --noImplicitAny compiler option). It's the same as the following annotated version:

function g(x: any, y: any): void { }
type G = typeof g;
// type G = (x: any, y: any) => void

fg本身的类型签名应用相同的规则会导致以下行为:

Applying the same rule to the type signatures of f and g themselves leads to the following behavior:

type Fprime = (x, y) => void; // --noImplicitAny yells at you here
// type Fprime = (x: any, y: any) => void

type Gprime = (x: any, y: any) => void;
// type Gprime = (x: any, y: any) => void

因此,当您编写(x, y) => void时,编译器会将xy解释为名称,而不是 types .由于可以省略类型,因此不能使用参数名称.我认为没有人喜欢这种方式,但是这种方式已经存在了很长时间,以至于显然是在图书馆中使用的,因此更改此设置将破坏实际代码.来自上面引用的同一评论:

So when you write (x, y) => void, the compiler interprets x and y as names and not as types. Since the type can be omitted, parameter names cannot. I don't think anyone likes this, but it's been this way for so long that it's apparently used in libraries, so changing this would break real-world code. From the same comment quoted above:

我认为进行这种更改为时已晚.由于当前的行为,将单个标识符解释为类型将是一个重大变化.

I think it is too late to make this sort of change. Because of the current behavior, interpreting a single identifier as a type would be a breaking change.


所以这是对这个问题的悲伤回答.也许他们可以使时光倒流,他们会这样做,以便参数名称是可选的并且类型是必需的,以便与类型理论符号更紧密地对齐,但是现在这就是我们所坚持的.


So that's the sad answer to this question. Maybe if they could go back in time they would make it so that the parameter name is optional and the type is required, to align more closely with type theory notation, but for now this is what we're stuck with.

希望有所帮助;祝你好运!

Hope that helps; good luck!

游乐场连结代码

这篇关于为什么必须在TS函数类型中指定参数名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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