Различать типы профсоюзов - PullRequest
3 голосов
/ 21 января 2020

Почему я не могу различить это объединение только информацией о том, что член x является строкой, а не числом? Почему я должен использовать литеральный тип?

type A = { x: string ; y: string }
type B = { x: number ; y: number }
type C = A | B

function fn(p: C) {
  if (typeof p.x === 'string') { 
    // Typescript is unable to infer p as A
    // Typescript infer p.y as (string | number), why not just string ?
  }
  // Typescript is capable of inferring p.x as number - good
  // But cannot infer p.y as number, why ?
}

Для меня невозможно вызвать функцию с таким типом, как этот {x: string, y: number}, так почему машинописный текст предполагает, что это возможно?

Ответы [ 2 ]

4 голосов
/ 21 января 2020

Непосредственно объяснение, почему компилятор Typescript не может различить guish тип объединения по typeof, но в справочниках говорится:

Существует три ингридиенты:

  1. Типы, имеющие общее свойство singleton type - дискриминант.
  2. Псевдоним типа, который принимает объединение эти типы - объединение.
  3. Тип охранников на общем свойстве.

Поэтому для сужения правильного типа необходимо свойство singleton type, Я бы использовал охрану нестандартного типа:

type A = { x: string ; y: string }
type B = { x: number ; y: number }
type C = A | B

function isA(obj: C): obj is A { 
  return typeof obj.x === 'string';
}

function isB(obj: C): obj is B { 
  return typeof obj.x === 'number';
}

function fn(p: C) {

  if (isA(p)) {
    // ...
  }

  if (isB(p)) {
    // ...
  }

}
2 голосов
/ 21 января 2020

Если вы можете express печатать в классах, я рекомендую сделать это:

class A { x: string; y: string; }
class B { x: number; y: number }
type C = A | B
function fn(p: C) {
    if (p instanceof A) {
        // { x: string; y: string; }
    }
    if (p instanceof B) {
        // { x: number; y: number }
    }

}

В этом случае вы можете использовать instanceof magi c. Это лучший способ. В противном случае вам нужно проверить все свойства, поскольку тип ключевого слова добавляет только определения к источнику.

...