Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何表示函数必须以多态方式返回与第一个参数相同的类型?_Javascript_Generics_Flowtype - Fatal编程技术网

Javascript 如何表示函数必须以多态方式返回与第一个参数相同的类型?

Javascript 如何表示函数必须以多态方式返回与第一个参数相同的类型?,javascript,generics,flowtype,Javascript,Generics,Flowtype,我一直在阅读有关泛型的文章,希望了解泛型如何在流中工作 我对使用流检查函数编程的函数签名的想法特别感兴趣 但是,我无法理解为什么以下各项不起作用: 当我尝试 /* @flow */ const identity = (c) => c; (identity: <T>(T) => T); // force flow to typecheck 编辑:试图澄清 我主要希望为函数提供一种类型作为参数,并了解如何多态地使用它们 也许这是一个更清楚的例子,说明我正在尝试键入的

我一直在阅读有关泛型的文章,希望了解泛型如何在流中工作

我对使用流检查函数编程的函数签名的想法特别感兴趣

但是,我无法理解为什么以下各项不起作用:

当我尝试

/* @flow */

const identity = (c) => c;

(identity: <T>(T) => T); // force flow to typecheck

编辑:试图澄清 我主要希望为函数提供一种类型作为参数,并了解如何多态地使用它们

也许这是一个更清楚的例子,说明我正在尝试键入的内容:

/* @flow */

type Transformer = <T>(T)=>T;

function transformAGivenThing(transform:Transformer, thing:*) {
  return transform(thing);
}

function transformAString(str:string):string {
  return str.toUpperCase();
}

transformAGivenThing(transformAString, 'thing');
/*@flow*/
型式变压器=(T)=>T;
函数transformAGivenThing(转换:Transformer,thing:*){
回归变换(物);
}
函数转换字符串(str:string):string{
return str.toUpperCase();
}
transformAGivenThing(transformAString,“thing”);
当我运行flow时,这会导致以下错误:

3: type Transformer = <T>(T)=>T;
                       ^ T. This type is incompatible with the expected param type of
9: function transformAString(str:string):string {
                             ^ string
9: function transformAString(str:string):string {
                                         ^ string. This type is incompatible with the expected param type of
13: transformAGivenThing(transformAString, 'thing');
                     ^ some incompatible instantiation of `T`
3:type Transformer=(T)=>T;
^T.此类型与的预期参数类型不兼容
9:函数转换字符串(str:string):字符串{
^串
9:函数转换字符串(str:string):字符串{
^字符串。此类型与的预期参数类型不兼容
13:transformAGivenThing(transformAString,“thing”);
^'T的某些不兼容的实例化`

编辑了关于添加到您的帖子中的内容

/* @flow */

const isStr = (str: string) => !!str;
const isNmbr = (nmbr: number) => !!nmbr;

function transformAny<T>(transformer: (T) => T, thing: T): T {
  return transformer(thing);
}

function transformString(thing: string): string {
  return !!thing ? thing.toUpperCase() : thing;
}

function transformNumber(thing: number): number {
  return !!thing ? thing * 10 : thing;
}

let s = transformAny(transformString, "1");

let n = transformAny(transformNumber, 5);

isStr(s);
// isStr(n);
// isNmbr(s);
isNmbr(n);
/*@flow*/
常量isStr=(str:string)=>!!str;
常量isNmbr=(nmbr:number)=>!!nmbr;
函数transformAny(transformer:(T)=>T,thing:T):T{
回流变压器(物);
}
函数transformString(thing:string):string{
return!!thing?thing.toUpperCase():thing;
}
函数编号(事物编号):编号{
返回!!东西?东西*10:东西;
}
设s=transformAny(transformString,“1”);
设n=transformAny(transformNumber,5);
isStr(s);
//isStr(n);
//isNmbr(s);
isNmbr(n);

取消对typechecking的2个调用的注释将引发错误匹配参数类型。我不认为您可以为其中一个参数声明自定义类型并返回相应的类型。这是我第一次看到这种语言,但它看起来非常类似于TypeScript。

编辑了关于添加到您的帖子的内容

/* @flow */

const isStr = (str: string) => !!str;
const isNmbr = (nmbr: number) => !!nmbr;

function transformAny<T>(transformer: (T) => T, thing: T): T {
  return transformer(thing);
}

function transformString(thing: string): string {
  return !!thing ? thing.toUpperCase() : thing;
}

function transformNumber(thing: number): number {
  return !!thing ? thing * 10 : thing;
}

let s = transformAny(transformString, "1");

let n = transformAny(transformNumber, 5);

isStr(s);
// isStr(n);
// isNmbr(s);
isNmbr(n);
/*@flow*/
常量isStr=(str:string)=>!!str;
常量isNmbr=(nmbr:number)=>!!nmbr;
函数transformAny(transformer:(T)=>T,thing:T):T{
回流变压器(物);
}
函数transformString(thing:string):string{
return!!thing?thing.toUpperCase():thing;
}
函数编号(事物编号):编号{
返回!!东西?东西*10:东西;
}
设s=transformAny(transformString,“1”);
设n=transformAny(transformNumber,5);
isStr(s);
//isStr(n);
//isNmbr(s);
isNmbr(n);

取消对typechecking的2个调用的注释将引发错误匹配参数类型。我不认为您可以为其中一个参数声明自定义类型并返回相应的类型。这是我第一次看到这种语言,但它看起来非常类似于TypeScript。

好,所以我最后提交了一个问题作为flow他们的回答是:

/* @flow */

type Transformer<T> = (T)=>T;

function transformAGivenThing(transform:Transformer<*>, thing:*) {
  return transform(thing);
}

function uppercaseAString(str:string):string {
  return str.toUpperCase();
}

console.log(transformAGivenThing(uppercaseAString, 'thing'));
/*@flow*/
型式变压器=(T)=>T;
函数transformAGivenThing(转换:Transformer,thing:*){
回归变换(物);
}
函数大写字符串(str:string):string{
return str.toUpperCase();
}
log(transformAGivenThing(大写字母“thing”);


正在发生的事情是,您需要使用类型配置
Transformer
泛型类型,但在这种情况下,因为它需要是多态的,所以配置应该是
*

确定的,所以我向flow提交了一个问题,询问如何执行此操作。他们的答案:

/* @flow */

type Transformer<T> = (T)=>T;

function transformAGivenThing(transform:Transformer<*>, thing:*) {
  return transform(thing);
}

function uppercaseAString(str:string):string {
  return str.toUpperCase();
}

console.log(transformAGivenThing(uppercaseAString, 'thing'));
/*@flow*/
型式变压器=(T)=>T;
函数transformAGivenThing(转换:Transformer,thing:*){
回归变换(物);
}
函数大写字符串(str:string):string{
return str.toUpperCase();
}
log(transformAGivenThing(大写字母“thing”);


发生的事情是,你需要用一个类型来配置
Transformer
泛型类型,但在这种情况下,因为它需要是多态的,所以配置应该是
*

嗯,也许我对我在这里试图实现的目标不够清楚。我将尝试更新我的问题。@rickard我已经编辑了我的帖子。这就是你试图对通用对象
transformer
所做的吗?嗯,也许我对我试图实现的目标还不够清楚。我将尝试更新我的问题。@rickard我已经编辑了我的帖子。调用
let s=transformer>时,这就是你试图对通用对象
transformer
所做的吗mAGivenThing(大写“thing”);
,返回的类型将是
any
。如果您检查我的更新答案,返回类型将与给定
变压器的返回类型相对应。适当的智能感知将拾取该类型。
*
any
*
之间存在差异
*
意味着延迟下游的类型检查,而
any
表示不进行类型检查。因为
*
将类型检查推迟到以后,所以在上面的示例中,泛型中的类型将在flow检查
uppercaseString
函数的点处解析。调用
时,让s=transformAGivenThing(uppercaseString,'thing');
,返回的类型将是
any
。如果您检查我的更新答案,返回类型将与给定
变压器的返回类型相对应。适当的智能感知将拾取该类型。
*
any
*
之间存在差异
*
意味着延迟下游的类型检查,而
any
表示不进行类型检查。因为
*
延迟类型检查
/* @flow */

type Transformer<T> = (T)=>T;

function transformAGivenThing(transform:Transformer<*>, thing:*) {
  return transform(thing);
}

function uppercaseAString(str:string):string {
  return str.toUpperCase();
}

console.log(transformAGivenThing(uppercaseAString, 'thing'));