无法返回Tuple、Typescript,而是将其解释为Array

rggaifut  于 2023-01-10  发布在  TypeScript
关注(0)|答案(2)|浏览(112)

我正在尝试给一个以前的开发人员写的通用函数的返回值添加类型安全,需要语法方面的帮助:

export function to(promise:Promise<any>) {  
  return promise
    .then(data => [null, data])
    .catch(err =>  [err, null]);
 }

这是一个非常简单的函数,它接收一个promise,并返回一个新的promise,其输出类型是元组[Error|null, <The First Promise's Return Type>|null]。本质上,第一个值将始终是一个错误,如果一个发生(否则null),第二个值将是等待第一个promise的结果(否则null)。

const [ err, result ] = await to(/*<API Call>*/);
if (err) {
    setError(err);
    // ...
} else if (result) {
    processApiResult(result);
    // ...
}

我知道下面的代码是错误的((T|null)[]不应该是“这些类型的数组”,而应该是“具有特定顺序的这些类型的元组”),但我一直在撞墙&这是我所能得到的最接近的了。

export function to<T>(promise:Promise<T>):Promise<(T|null)[]|[Error, null]> {  
  return promise
    .then(data => [null, data])
    .catch(err => [err as Error, null]);
 }
 
const [ err, result ] = await to(api.changePassword(username, password));  
// const error : string | Error | null
// const result : string | null

第一个参数应为Error | null(而不是| string),第二个参数正确为string | null

bpzcxfmw

bpzcxfmw1#

如果您确定to()返回的元组不会发生变化,则可以使用constAssert来键入此函数。

export function to<T>(promise:Promise<T>):Promise<readonly [Error | null, T | null]>  {  
  return promise
    .then(data => [null, data] as const)
    .catch(err => [err as Error, null] as const);
}

const [ err, result ] = await to(api.changePassword(username, password));  
// err: Error | null
// result: string | null

这是因为as const会将数组文本的类型转换为只读元组。
如果出于某种原因不希望元组是只读的,那么还可以执行以下操作:

export function to<T>(promise:Promise<T>):Promise<[Error | null, T | null]>  {  
  return promise
    .then(data => [null, data] as [null, T])
    .catch(err => [err as Error, null] as [Error, null]);
}

const [ err, result ] = await to(api.changePassword(username, password));  
// err: Error | null
// result: string | null

无论哪种方式,您只需要告诉编译器to()返回的值是固定大小的元组,而不是数组。

x8diyxa7

x8diyxa72#

function to<T>(promise:Promise<T>):Promise<[Error|null,T|null]> {
    return promise
        .then((data):[null,T] => ([null, data]))
        .catch((err) =>( [err, null]));
}

async function func() {
    const [ err, result ] = await to<string>(new Promise(resolve => resolve));
    console.log(err,result)
}

相关问题