简体   繁体   中英

Conditional interface in TypeScript

I have the following case: two different interfaces (A, B) and one function which takes a parameter props as a conditional interface / union type. But I cannot use prop if it isn't declared in both interfaces.

Example :

interface A {
    name: string
};

interface B {
    age: number
};

function foo(props: A | B) {
    return props.name;
}

This is correct - you don't know if the name key exists on your props object.

You have two options:

1

function foo(props: A | B): string | undefined {
  if ('name' in props) {
    return props.name
  }
}

2.

interface A {
  name: string
  age?: undefined
}

interface B {
  name?: undefined
  age: number
}

function foo(props: A | B): string | undefined {
  return props.name
}

Why?

Typescript is correctly warning you because an object which does not have the name key is not the same as an object where the name key is undefined. Imagine this:

const a = {
  // name is missing
  age: 1
}

const b = {
  name: 'test',
  age: undefined
}

Object.keys(a) == ['age']
Object.keys(b) == ['name', 'age']

if ('age' in b) {
  console.log('this is true')
}

if ('name' in a) {
  throw new Error(`This is false`)
}

You could do it like this:

function foo(props: A | B) {
    if ((props as A).name) {
        return (props as A).name;
    }
    return undefined;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM