简体   繁体   English

是否可以在TypeScript中组合用户定义的类型保护?

[英]Is it possible to combine user defined type guards in TypeScript?

Given 特定

type Maybe<T> = T | undefined;

class Obj {
    jbo: Maybe<Jbo>;
}

, is it possible to define a function that given a o: Maybe<Obj> asserts the types of both o and o.jbo ? ,是否可以定义一个给定o: Maybe<Obj>的函数o: Maybe<Obj>断言oo.jbo的类型?

I'm thinking of something like: 我想的是:

function everythingIsDefined(o: Maybe<Obj>):o is Obj && o.jbo is Jbo {
    // checks in here
}

A user-defined typeguard can only return one x is T . 用户定义的typeguard只能返回一个x is T Luckily, you can use unions and intersections in your choice of T . 幸运的是,您可以在您选择的T使用工会和交叉点。 So, for example: 所以,例如:

function everythingIsDefined(o: Maybe<Obj>): o is Obj & {jbo: Jbo} {
    return typeof o !== 'undefined' && typeof o.jbo !== 'undefined';
}

The everythingIsDefined function asserts that the input is both an Obj (as opposed to undefined), and an object whose jbo property is a Jbo (as opposed to undefined). 所述everythingIsDefined函数断言,输入既是 Obj (相对于未定义的), 一个对象,其jbo属性是一个Jbo (相对于未定义)。 So you can use it like this: 所以你可以像这样使用它:

if (everythingIsDefined(obj)) {
  console.log(obj.jbo.toString()) // no error
} 

Yeah, you can pull that off: 是的,你可以把它拉下来:

type Maybe<T> = T | undefined;
type DeepMaybe<T> = { [K in keyof T]: Maybe<T[K]> };

class Obj {
    jbo: Jbo;
}

function everythingIsDefined<T>(o: DeepMaybe<T>): o is T {
    return false;
}

And then: 接着:

let obj: DeepMaybe<Obj> = {} as Obj;
if (everythingIsDefined(obj)) {
    // type of obj.jbo is Jbo
} else {
    // type of obj.jbo is Maybe<Jbo>
}

( code in playground ) 游乐场代码

Explanation: 说明:
There's probably no way to acomplish that with the types you provided (that is Obj.jbo: Maybe<Jbo> ). 可能无法使用您提供的类型(即Obj.jbo: Maybe<Jbo> )来完成。
Instead, the class Obj needs to define its properties as the actual type, but if you type your variable as DeepMaybe<Obj> (or anything else instead of Obj ) then you get the same thing. 相反,类Obj需要将其属性定义为实际类型,但如果您将变量键入为DeepMaybe<Obj> (或其他任何而不是Obj ),那么您将得到相同的东西。

The difference is now, because DeepMaybe is a mapped type you have better control on how to create the type guard. 现在不同了,因为DeepMaybe是一种映射类型,您可以更好地控制如何创建类型保护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 以编程方式从界面创建打字稿用户定义的类型防护 - Programatically Create Typescript User Defined Type Guards from Interface 打字稿中的类型保护正在缩小到从不打字 - Type guards in typescript are narrowing to never type Typescript 自定义类型守卫和数组操作 - Typescript custom type guards and array operations 是否可以在 Strapi v4 中创建具有用户定义类型的自定义组件? - Is that possible to create a custom component with user defined type in Strapi v4? TypeScript `is` 类型谓词(用户定义的类型保护函数)来实现幂等对象类型 - TypeScript `is` type predicates (user-defined type guard functions) to implement idempotent object types 是否可以在 TypeScript 注释中组合多种类型的成员? - Is it possible to combine members of multiple types in a TypeScript annotation? 当我在 TypeScript 中将它们与 ReturnType 一起使用时,类型保护不起作用 - Type guards doesn't work when I use them with ReturnType in TypeScript 检查 object 是否属于类型(类型定义为数组) - TypeScript - Check if object is of type (type is defined as array) - TypeScript 打字稿:是否可以引用类型别名 - Typescript: Is it possible to reference type aliases Typescript - 常量名称已在类型中定义 - Typescript - const name already defined in type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM