我可以向Typescript元组添加一个方法吗(或者,等价地,将一个对象解构为一个数组)?

cnh2zyt3  于 2022-11-18  发布在  TypeScript
关注(0)|答案(1)|浏览(117)

假设我希望我的函数是一个简单的Typescript二元组:

type SuperTuple = [number, string]
function torgle(value: string): SuperTuple { 
  return [value.length, value]
}

这样我就可以方便地对torgle的返回值进行反结构化:

const [index, label] = torgle('pizza')
>> [5, 'pizza']

但我还想定义一种特殊的map函数,它只对第一个值(number)进行运算,并通过第二个值:

const hmmm = torgle('pizza').mapIndex(i => i * i)
>> [25, 'pizza']

在Javascript中,我可以直接添加mapIndex函数,所以我几乎可以让它像这样工作:

function supTup(num: number, str: string): SuperTuple {
    const tup: [number, string] = [num, str]
    return Object.assign(tup,
        {mapIndex: (f: (x: number) => number) => supTup(f(num), str)} 
    )
}

function torgle(value: string): SuperTuple {
    return supTup(value.length, value)
}

但是Typescript并不满意,它可能允许我使用一个扩展Iterator的生成器或类,但是我不太确定在这种情况下会是什么样子。
如何输入SuperTuple和/或torgle,以便 * 既 * 将SuperTuple反结构为数组 又 * 在其上调用我的自定义方法?

const [string1, label1]: SuperTuple = torgle('pizza')
const [string2, label2]: SuperTuple = torgle('pasta').mapIndex(i => i * 2)
piok6c0g

piok6c0g1#

您可以将SuperTuple定义为普通[number, string]元组与包含mapIndex()方法的对象类型的交集:

type SuperTuple = [number, string] & 
  { mapIndex(f: (x: number) => number): SuperTuple };

在英语中,我会读为:“SuperTuple既是[number, string],也是具有mapIndex()方法的东西,该方法接受数字到数字的回调并返回另一个SuperTuple
现在编译器不会再抱怨了:

const hmmm = torgle('pizza').mapIndex(i => i * i); // okay
//const hmmm: SuperTuple

Playground代码链接

相关问题