While you cannot impose such an arbitrary constraint at compile time, you can create types that force the user to call the functions that perform these checks, and then rely on these invariants in your code using the proprietary type
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;
}
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 MyData = {a:PositiveNumber, b:StringOfMinLength<3>}
let myObj: MyData = {
a: asPositiveNumber(0),
b: asStringOfMinLength("Test", 3),
}
Math.sqrt(myObj.a)
myObj.b[2]
let myNotOkObject: MyData = {
a: -1,
b: "Test"
}
let a = 10;
let b = "Test"
if(isPositiveNumber(a) && isStringOfMinLength(b, 3))
{
let myOtherObj: MyData = { a, b }
} else {
}
, (ex Math.sqrt(myObj.a)), . , .
.
Edit
, , , , , . 10x @AluanHaddad .