skip to Main Content

I have this example

class Test {
  firstName: string;
  lastName:string;

}

Now I would like typescript to validate this

let text = "firstName:aName lastName:bName"

I know of keyof but I want to take it forther and when I write fi in a string it will be able to present firstName and the same with lastName as it gets seperated by space or comma.

Is this possible in typescript?

I am building a library a react-native library that would make styling easier.

in react-native you write style as

style={{color:"black", fontSize:12 etc}}

I am building a Library that will make it possible to shorter the style and make it easier to write so it would be as

css="co:black fos:12 bac:white etc.."

The issue is I would like typescript to be able to validate this and also be able to include some random user class that is inlcuded in user theme

css="co:black fos:12 bac:white container etc.."

container is a user define style that exists in the user theme so typescript needs not validate this. only validate names that are predefined as col or color

I could build a cli that generates the type dynamicly but I am not sure how, the ts part how not the cli

2

Answers


  1. You can split the string and validate its parts, if a substring is of format key:value, validate the key against your validation object and the value against allowed interpolatable values:

    Playground

    type Split<T extends string, D extends string> = 
      T extends `${infer A}${D}${infer B}` ? [A, ...Split<B, D>] : [T]
    
    type User = {
      firstName: string,
      lastName: string,
      age: number
    }
    
    type Interpolatable = string | number | bigint | boolean | null | undefined;
    
    type Validate<T extends object, S extends string> = (
      Split<Split<S, ' '>[number], ':'> extends infer A ? 
        A extends [infer B, infer C] ? 
          B extends keyof T ? 
            T[B] extends Interpolatible ? 
              C extends `${T[B]}`? 
                true : 
              false :
            false : 
          false : 
          A extends [string] ? true : false : 
        false
      ) extends true ? S : never
    
    function CSSMaker<T extends object>() {
      return <S extends string>(str: Validate<T, S>) => {
        return str;
      };
    }
    
    const maker = CSSMaker<User>();
    
    const css = maker('firstName:aName lastName:bName container age:29');
    const css1 = maker('firstName:aName lastName:bName container age:twentynine'); // error, invalid age, should be a number
    const css2 = maker('firstName2:aName lastName:bName container age:29'); // error, invalid firstName2 key
    
    Login or Signup to reply.
  2. If I understand you correctly, your question aims at having TS autocompleting for parts of a string.

    I do not think this is possible.

    const noAutoCompletion : `foo-${string}` = 'foo-bar';
    const hasAutoCompletion : 'foo-bar' = 'foo-bar';
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search