运算符在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型。