打字稿:泛型的自定义类型防护?

时间:2020-07-17 14:27:09

标签: typescript

我有两个相关的类型,我想用一个自定义类型防护来区分它们。它们是泛型类型(在现实生活中,它们具有多个类型的arg,但这对于SO而言是简化的。)

我的问题是:是否可以编写通用的isCat类型防护,以返回对任何猫类型Cat<T>都有效的谓词(返回true)?在我的真实应用中,T有许多可能的选项,因此将它们全部写出来是不切实际的。

class Dog<T> {
  age: number|T = 1
  bark() { console.log("woof")}
}

class Cat<T> {
  age: number|T = 1
  meow() { console.log("meow")}
}

function isCat(animal: any): animal is Cat { // this is invalid, generic type Cat requires 1 arg
  return 'meow' in animal
}

function f(animal: any) {
  if (isCat(animal))
    animal.meow()
}
f(new Cat<number>())
f(new Dog<number>())

1 个答案:

答案 0 :(得分:2)

您可以使用保留字unknown来告诉打字稿它是猫,具有未知的模板化参数

class Dog<T> {
  age: number|T = 1
  bark() { console.log("woof")}
}

class Cat<T> {
  age: number|T = 1
  meow() { console.log("meow")}
}

function isCat(animal: any): animal is Cat<unknown> {
  return 'meow' in animal;
}

function f(animal: any) {
  if (isCat(animal))
    animal.meow()
}

f(new Cat<number>())
f(new Dog<number>())

我也会做类似的事情:

class Animal<T> {
  age: number|T = 1
}

class Dog<T> extends Animal<T> {
  bark() {
    console.log('woof');
  }
}

class Cat<T> extends Animal<T> {
  meow() {
    console.log('meow');
  }
}

function isCat(animal: Animal<unknown>): animal is Cat<unknown> {
  return 'meow' in animal;
}

function f(animal: Animal<unknown>) {
  if (isCat(animal))
    animal.meow()
}

f(new Cat<number>())
f(new Dog<number>())