Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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
Arrays 在TypeScript中定义不同泛型类型的数组 接口指令{ 承诺:承诺, 回调?:($html:JQuery,数据:未知)=>void } 常量arr:指令[]=[ {promise:promise.resolve({foo:'bar'}),回调:($html,data)=>console.log(data.foo)}, {promise:promise.resolve({bar:'foo'}),回调:($html,data)=>console.log(data.bar)} ];_Arrays_Typescript_Generics - Fatal编程技术网

Arrays 在TypeScript中定义不同泛型类型的数组 接口指令{ 承诺:承诺, 回调?:($html:JQuery,数据:未知)=>void } 常量arr:指令[]=[ {promise:promise.resolve({foo:'bar'}),回调:($html,data)=>console.log(data.foo)}, {promise:promise.resolve({bar:'foo'}),回调:($html,data)=>console.log(data.bar)} ];

Arrays 在TypeScript中定义不同泛型类型的数组 接口指令{ 承诺:承诺, 回调?:($html:JQuery,数据:未知)=>void } 常量arr:指令[]=[ {promise:promise.resolve({foo:'bar'}),回调:($html,data)=>console.log(data.foo)}, {promise:promise.resolve({bar:'foo'}),回调:($html,data)=>console.log(data.bar)} ];,arrays,typescript,generics,Arrays,Typescript,Generics,鉴于上述情况,我希望TypeScript能够识别回调函数中的数据参数与Promise的解析类型相同 如果它是独立的,我可以做: interface Instruction { promise: Promise<unknown>, callback?: ($html: JQuery, data: unknown ) => void } const arr: Instruction[] = [ { promise: Promise.resolve({ foo: 'ba

鉴于上述情况,我希望TypeScript能够识别回调函数中的数据参数与Promise的解析类型相同

如果它是独立的,我可以做:

interface Instruction {
  promise: Promise<unknown>,
  callback?: ($html: JQuery, data: unknown ) => void
}

const arr: Instruction[] = [
  { promise: Promise.resolve({ foo: 'bar' }), callback: ($html, data) => console.log(data.foo) },
  { promise: Promise.resolve({ bar: 'foo' }), callback: ($html, data) => console.log(data.bar) }
];
接口指令{
承诺:承诺,
回调?:($html:JQuery,data:T)=>void
}

但是,我该如何定义数组,其中
T
在每行上的含义可能不同?

也许它会帮助您:

type JQuery='JQuery'
接口指令{
承诺:承诺,
回调?:($html:JQuery,data:T)=>void
}
constbuilder=(arg:T):指令=>({promise:promise.resolve(arg),回调:($html,data)=>data})
常数arr=[
生成器({foo:'bar'}),
生成器({bar:'foo'}),
];
如果这个数组是可变的,事情就会变得复杂

更新

您必须添加额外的逗号
,因为没有
TS认为您试图使用某种
react jsx
语法。 你应该只使用箭头功能。它与
功能
一样正常工作。
您可以使用

而不是
额外的逗号,这实际上是的规范用例,在TypeScript中不直接支持(大多数具有泛型的语言也不直接支持它们,因此这不是TypeScript的一个特殊缺点)。有一个开放的特性请求,要求这样做,但它不是TS4.1语言的一部分

TypeScript中的泛型是“通用的”,这意味着当我说
class Foo{…}
时,我的意思是它适用于所有可能的类型参数
T
。这使得
Foo
的消费者可以指定
T
的值,并根据自己的意愿使用它,而
Foo
的提供者需要考虑所有可能性

您试图描述的异构集合需要“存在”泛型。在某种意义上,您希望
接口指令{…}
意味着存在一个类型参数
T
。这意味着
指令
的提供者可以指定
T
的值,并根据需要使用它,而
指令
的使用者需要考虑所有可能性

有关通用与存在量化泛型的更多信息,请参阅


虽然TypeScript中没有直接支持存在主义,但有间接支持。普遍意义和存在意义之间的区别与谁在看类型有关。如果你转换生产者和消费者的角色,你就会有类似于生存的行为。这可以通过回调来实现。所以存在主义可以用TypeScript编码

让我们看看如何为
指令
执行此操作。首先,让我们将
指令
定义为一个通用的泛型,即您提到的“独立”版本(我正在删除此代码中的
JQuery
依赖项):

SomeInstruction
是一个函数,它调用一个函数,该函数为任何
T
接受
指令并返回结果。请注意,
SomeInstruction
本身如何不再依赖于
T
。您可能想知道如何获得
SomeInstruction
,但这也是相当简单的。让我们创建一个帮助函数,将任何
指令
转换为
SomeInstruction

interface Instruction<T> {
    promise: Promise<T>,
    callback?: (data: T) => void
}
type SomeInstruction = <R>(cb: <T>(instruction: Instruction<T>) => R) => R;
根据需要检查所有类型


实际上,使用
SomeInstruction
比使用
指令要复杂一些,因为它需要回调。但这并不可怕,并且再次允许
T
类型参数以消费者不知道实际
T
类型的方式出现,因此必须将其视为任何可能的
T

const arr: SomeInstruction[] = [
    someInstruction({ 
      promise: Promise.resolve({ foo: 'bar' }), 
      callback: (data) => console.log(data.foo) 
    }),
    someInstruction({ 
      promise: Promise.resolve({ bar: 'foo' }), 
      callback: (data) => console.log(data.bar) 
    })
]
//在此处写出T以明确
arr.forEach(someInstruction=>someInstruction((i:Instruction)=>{
i、 承诺。那么(i.callback);//起作用了
}))
//但没有必要:
arr.forEach(someInstruction=>someInstruction(i=>{
i、 承诺。那么(i.callback);//起作用了
}))
很好


还有其他解决办法,但存在主义是你真正想要的。为了完整起见,以下是一些可能的变通方法,我将提及但不实施:

  • 放弃类型安全,使用
    any
    unknown
    并使用类型断言返回所需的类型。布莱奇

  • 在将类似
    [T1,T2,T3]
    的类型转换为相应的
    [Instruction,Instruction,Instruction]
    类型时,请使用。但是,这不适用于
    push()
    ,因此您也需要设法解决这个问题

  • 重构
    指令
    ,以便不需要/公开泛型。无论消费者打算用
    指令做什么,它都必须独立于
    T
    (例如,我可以编写
    I.promise.then(I.callback)
    ,但我不能做太多其他事情,对吗?),所以制作一个
    指令
    泛型函数,它需要一个有效的promise和callback对来创建,并返回一些非泛型的东西,包括您需要的任何功能,仅此而已。从某种意义上说,这是一个“精简”的存在主义,不允许使用者单独访问内部承诺回调对



在您的实际代码中,
arr
是否是一个长度和类型在编译时已知的不可变数组
const someInstruction = <T,>(i: Instruction<T>): SomeInstruction => cb => cb(i);
const arr: SomeInstruction[] = [
    someInstruction({ 
      promise: Promise.resolve({ foo: 'bar' }), 
      callback: (data) => console.log(data.foo) 
    }),
    someInstruction({ 
      promise: Promise.resolve({ bar: 'foo' }), 
      callback: (data) => console.log(data.bar) 
    })
]
// writing out T for explicitness here
arr.forEach(someInstruction => someInstruction(<T,>(i: Instruction<T>) => {    
    i.promise.then(i.callback); // works
}))

// but it is not necessary:
arr.forEach(someInstruction => someInstruction(i => {    
    i.promise.then(i.callback); // works
}))