'typescript asserts if returns not null (with typeguard)
I am trying to check some property of a variable with a regular Expression and if that matched, I want the type of that variable be inferred to a more specific type.
I have an example in the typescript playground:
type xN = `x${number}`;
const reg = new RegExp("x([0-9]+)");
function check(s:string):RegExpMatchArray | null /* asserts s is xN*/{
return s.match(reg);
}
declare const test :string;
const match = check(test);
if(match){
// test should be of type xN now
match.groups // use that non-null match variable, too...
}
Is there a way to do that with one function in (TS 4.5.4)? If not, how would you do it neatly?
Solution 1:[1]
Base on Single responsibility principle, I don't think you should do both in a function. It makes your application more complicated.
Instead of that, you can break it into two functions like that:
type xN = `x${number}`;
const reg=new RegExp("x([0-9]+)");
function isXn(s: string): s is xN {
return true
}
function check(s: xN):RegExpMatchArray {
return s.match(reg)!; // !: since xN is always match reg
}
declare const test :string;
if(isXn(test)){
//test is xN now
const match = check(test);
match.groups // use that non-null match variable, too...
}
Solution 2:[2]
If you just want to know if the string is xN
type xN = `x${number}`;
const reg=new RegExp("x([0-9]+)");
function check(input:string): input is `${string}${xN}${string}` {
return !!input.match(reg)
}
let checkStr:string
if (check(checkStr)) {
checkStr
// ^? `x${number}`(xN)
} else {
checkStr
// ^? string
}
If you know exactly the string (string is constant), it allows you to know the correct string.
function getValue<T extends string>(input:T){
const reg=new RegExp("x([0-9]+)");
const match = input.match(reg)
if(match) return match[1] as T extends `x${infer W}` ? W : null
else return null
}
const knowStr1 = "x356363"
const value1 = getValue(knowStr1)
// ^? "356363"
const knowStr2 = "hi"
const value2 = getValue(knowStr2)
// ^? null
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Long Nguyen Duc |
| Solution 2 |
