Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript Typings To Use Conditional Logic #31

Closed
bezreyhan opened this issue Aug 5, 2019 · 9 comments
Closed

Typescript Typings To Use Conditional Logic #31

bezreyhan opened this issue Aug 5, 2019 · 9 comments

Comments

@bezreyhan
Copy link

Hello, I wanted to reference a previously closed issue: #14

I just tested the following code and was still getting type errors:

const waiter = (): Promise<boolean> => Promise.resolve(true);

const test = async (): Promise<boolean> => {
  const [err, res] = await to<boolean>(waiter());
  if (err) {
    return false;
  }

  return res;
};

Typescript complains that res may be undefined. But since we have handled the error case we know that res is defined.

Thank you

@rizaldirnm
Copy link

use res!.data.everything
to get safe deeply access object, read more detail here https://codewithstyle.info/Deep-property-access-in-TypeScript/

@bezreyhan
Copy link
Author

@Rizaldinurm using ! tells TS to ignore the type so when you use ! you lose type safety.

The ideal situation is that TS makes sure you have checked that error is undefined (or that res is defined) before using res.

@lucaspoffo
Copy link

lucaspoffo commented Oct 29, 2019

@bezreyhan When the return type is an Array you cannot infer the values between each other,
but if the return type is an Object you can do it, like this:

async function to<T, U = Error>(promise: Promise<T>): Promise<{ error: U; data: undefined } | { error: null; data: T }> {
  return promise.then((data: T) => ({ error: null, data }))
    .catch((error: U) => ({ error, data: undefined }))
}


async function successAsync(): Promise<{ value: number }> { return { value: 5 } }

async function test() {
  const result = await to(successAsync())
  if (result.error) {
    console.log('Found error in successAsync')
    return // don't forget
  }
  console.log(result.data.value) // No type error
}

test()

@bezreyhan
Copy link
Author

@lucaspoffo I have not tried this myself but it looks like conditional types with arrays should be possible: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#example-2

@lucaspoffo
Copy link

@bezreyhan You're right, arrays works too, but you can't separate in 2 variables:

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

async function successAsync(): Promise<{ value: number }> { return { value: 5 } }

async function testA() {
  const result = await to(successAsync())
  if (result[0]) {
    console.log('Found error in successAsync')
    return // don't forget
  }
  console.log(result[1].value) // No type error
}

async function testB() {
  const [err, result] = await to(successAsync())
  if (err) {
    console.log('Found error in successAsync')
    return
  }
  console.log(result.value) // Type error
}

@JFGHT
Copy link

JFGHT commented Sep 16, 2020

@lucaspoffo, @bezreyhan

How about this #46?

@bezreyhan
Copy link
Author

@JFGHT I haven't tested it but that look good to me!

@mrmartineau
Copy link

I think this can now be closed because v3.0.0 with the fixes in #46 was released yesterday.

@k1ngbanana
Copy link

async function testA() {
  const result = await to(successAsync())
  if (result[0]) {
    console.log('Found error in successAsync')
    return // don't forget
  }
  console.log(result[1].value) // No type error
}

async function testB() {
  const [err, result] = await to(successAsync())
  if (err) {
    console.log('Found error in successAsync')
    return
  }
  console.log(result.value) // Type error
}

so is there any why to separate into two variables and show no err? the res[0] and res[1] is not quite clean for each time to evoke this function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants