繁体   English   中英

使用条件属性/限制在typescript中定义类型

[英]Define a type in typescript with conditional properties / limits

我是打字稿的新手,并学会了如何定义自定义类型,如:

类型T = {a:数字,b:任意}

是否可以使用类中定义的类型构造函数在TypeScript中为长度大于2的所有字符串集定义类型?

或者可能为所有大于0的数字集定义一个类型?

虽然您无法在编译时强制执行此类任意约束,但您可以创建强制用户调用执行这些验证的函数的类型,然后使用品牌类型依赖代码中的这些不变量

type PositiveNumber =  number & { positive: true}
type StringOfMinLength<T extends number> =  string & { minLegth: T}

type T = {a:PositiveNumber, b:StringOfMinLength<3> }

function isPositiveNumber(value: number): value is PositiveNumber {
    if( value < 0 ) return false
    return  true;
}
function asPositiveNumber(value: number) {
    if( !isPositiveNumber(value) ) throw new Error("Not ok")
    return value; // type guard above, value will now be a PositiveNumber 
}

function isStringOfMinLength<T extends number>(value: string, length: T): value is StringOfMinLength<T> {
    if( value.length < length ) return false;
    return true;
}

function asStringOfMinLength<T extends number>(value: string, length: T): StringOfMinLength<T> {
    if(!isStringOfMinLength(value, length) ) throw new Error("Not ok")
    return value; // type guard above, value will now be a PositiveNumber 
}

type MyData = {a:PositiveNumber, b:StringOfMinLength<3>}
let myObj: MyData = {
    a: asPositiveNumber(0),
    b: asStringOfMinLength("Test", 3),
}

Math.sqrt(myObj.a) // a will be greater then 0
myObj.b[2] // index will exist, length greater then 3

let myNotOkObject: MyData = {
    a: -1, // will be a compile error, the checking function is not called
    b: "Test" // this will also be an error event though it satisfies the constraint since we don't call the appropriate function
}

// we can also use the type guard version instead (is*) of the assertion version (as*)
let a = 10;
let b = "Test"
if(isPositiveNumber(a) && isStringOfMinLength(b, 3))
{
    let myOtherObj: MyData = { a, b } // a and b are PositiveNumber and respectively StringOfMinLength<3>
} else {
    // handle case when they are not what was expected
}

您可以在任何需要基本类型的地方使用品牌类型(例如Math.sqrt(myObj.a) ),但不能将基本类型直接分配给品牌类型的字段。 这对于实际代码是否有价值取决于您和您的用例。

本文对品牌类型进行了更多讨论。

编辑

添加了品牌类型创建函数的类型保护版本,这样您就可以检查不变量是否为真并自行处理错误情况而不是抛出错误。 10x到@AluanHaddad的想法。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM