运算符在Typescript中

运算符在Typescript中,typescript,Typescript,有人能解释一下操作员是如何在typescript中为typeguard工作的吗?下面有一些接口和自定义类型的保护 interface kekType { kek: string; } interface kekType2 { kek: string; lol: string; } interface kekType3 { keks: string; } const funckek = (akek: kekType, istrue: boole

有人能解释一下操作员
是如何在typescript中为typeguard工作的吗?下面有一些接口和自定义类型的保护

  interface kekType {
   kek: string;
  }
  interface kekType2 {
   kek: string;
   lol: string;
  }
  interface kekType3 {
   keks: string;
  }

  const funckek = (akek: kekType, istrue: boolean): akek is kekType2 => istrue;
  const funckek2 = (akek: object, istrue: boolean): akek is kekType2 => istrue;
两个变量将被转换

  let aaa = {} as kekType;
  let aaa2 = {} as kekType3
是否为if/else范围创建类型

  if (funckek(aaa, true)) {
   console.log(aaa); // let aaa: kekType2
  }
  
  console.log(aaa); // let aaa: kekType

  if (funckek2({} as kekType3, true)) {
   console.log(aaa2); // let aaa2: kekType3
  }  
或者,如果这些类型无法更改,它会以某种方式组合这些类型

  if (funckek2(aaa2, true)) {
   console.log(aaa2); // let aaa2: kekType3 & kekType2
  }

我真的不明白它到底是怎么工作的。我希望有人能对此有所了解。

将TypeScript中的typeguard想象成一个可以完成两件事的函数。首先,它返回一个布尔值。从这个意义上说,

const-isString(x:unknown):x是string=typeof x=='string'

const-isString(x:unknown):boolean=typeof x=='string'

它们是等价的。然而,typeguard提供了一个超出返回boolean函数的额外功能:它帮助TypeScript缩小代码中可能的类型

假设您有以下代码:

const isString = (x:unknown):x is string => typeof x === 'string'
const isBoolean = (x:unknown):x is boolean => typeof x === 'boolean'
const multiplyByTwo = (x:number) => x*2

function myFn(a: string|number|boolean) {
  // right here, typescript knows 'a' could be a string, number, or boolean
  multiplyByTwo(a) // Error! 'multiplyByTwo' cannot take a string or boolean

  if(isString(a)) return
  // now here, typescript knows 'a' could only be a number or boolean
  multiplyByTwo(a) // Error! 'multiplyByTwo' cannot take a boolean

  if(isBoolean(a)) return
  // now here, typescript knows 'a' could only be a number
  multiplyByTwo(a) // Success
}
我不知道您的typeguards中的
istrue
参数是用来做什么的,但是如果我为您的域编写typeguards,我会将它们写成

const isKekType = (a: unknown): a is kekType => 
  typeof a === 'object' && a.hasOwnProperty('kek')
const isKekType2 = (a: unknown): a is kekType2 =>
  typeof a === 'object' && a.hasOwnProperty('kek') && a.hasOwnProperty('lol')
const isKekType3 = (a: unknown): a is kekType3 =>
  typeof a === 'object' && a.hasOwnProperty('keks')
请注意,TypeScript是“duck-typed”,这意味着即使您的
kekType2
没有显式扩展
kekType
,它也具有
kekType
所具有的所有属性,因此任何
kekType2
也将是
kekType

如果你真的想让你的typeguards更加具体,你可以这样忽略duck输入:

const isKekType = (a: unknown): a is kekType => 
  typeof a === 'object' && a.hasOwnProperty('kek') && Object.keys(a).length === 1
const isKekType2 = (a: unknown): a is kekType2 =>
  typeof a === 'object' && a.hasOwnProperty('kek') && a.hasOwnProperty('lol') && Object.keys(a).length === 2
const isKekType3 = (a: unknown): a is kekType3 =>
  typeof a === 'object' && a.hasOwnProperty('keks') && Object.keys(a).length === 1
最佳实践是typeguard函数只接受一个参数:检查类型的值。所以我不会在typeguards中传递一个
istrue:boolean
第二个参数。

对于类:

您可以向每个类添加名为“type”的只读属性,并检查此属性以获取类的类型

class A {
   public readonly type = "A"
   public kek = "someValue"
}
class B {
   public readonly type = "B"
   public kek = "randomValue"
   public lol = "LoL"
}
class C {
   public readonly type = "C"
   public keks = "keks"
}
现在可以在函数中执行以下操作:

function (someObject: A | B | C) {
  switch(someObject.type) {
          case "A":
            // do something (someObject is automatically casted to class A)
            break
          case "B":
            // do something (someObject is automatically casted to class B)
            break
          case "C":
            // do something (someObject is automatically casted to class C)
            break
          default: 
            throw new Error("someObject has an invalid type")
        }
}

总的来说,你已经把事情解释得很好了,但是你不能逃避鸭子式的打字,也不应该尝试。您的最后一个示例并没有忽略duck Typing,我了解guards是如何工作的,并且使用该参数只是为了尝试另一种方法。我的主要问题是什么是,你很好地解释了我。所以非常感谢你)我的回答)Danke schön,@Max。“x是y”是一个y型,也就是y型。