2

demo:

function getValue(data: unknown) {
  // return data?.value // error
  // or
  // use "value" in data to narrow the scope
  if (typeof data === 'object' && data && 'value' in data) {
    return data.value; // error
  }
  return '';
}

I don't want to use assertions data is similar to the data returned by a request

2
  • Are you looking for return data?.value ?? '';?
    – jh316
    Commented Jan 2, 2022 at 8:20
  • Unfortunately, you cannot do it this simply right now, typescript isn't able to infer types from the in operator very well at the moment. Either use type assertions or you could write a type guard like const hasValue = (obj: any): obj is {value: unknown} => typeof obj === 'object' && obj && 'value' in obj and then use it if(hasValue(data))
    – jabuj
    Commented Jan 2, 2022 at 21:12

2 Answers 2

1

As Alex Chashin commented,typescript isn't able to infer types from the in operator very well at the moment.So maybe I need this function

function hasValue(it: unknown): it is ({ value: string }) {
    return typeof it === "object" && it !== null && "value" in it;
}

function hasStringValue(it: unknown): it is ({ value: string }) {
    return hasValue(it) && typeof it.value === "string";
}

Using type predicates

0

You can use generic types. For example:

type IData = {value: string}

function getValue<T extends IData>(data: T) {
  if (typeof data === 'object' && data && 'value' in data) {
    return data.value;
  }
  return '';
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.