Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validating Records doesn't work since no related code is generated #725

Closed
rinart73 opened this issue Jul 29, 2023 · 4 comments
Closed

Validating Records doesn't work since no related code is generated #725

rinart73 opened this issue Jul 29, 2023 · 4 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@rinart73
Copy link

📝 Summary

  • Typia Version: 4.1.8
  • Expected behavior: Validating both keys and values in Record works.
  • Actual behavior: Validating both keys and values in Record doesn't work because no related code is generated.

Record<KeyType, ValueType> are not validated, no code is being generated for validating keys or values, no matter if the types are built-in (string, number) or custom.

⏯ Playground Link

https://typia.io/playground/?script=JYWwDg9gTgLgBDAnmYBDOAzKERwERIqp4DcAUGQPQBU1Zc1cAAmKjDAKZQB2cAegG1UAWgBeAfQC6AagAk9RkxDBuAGQ7cA5jAAWcAMwLKZQhzgBpDojgBeOAGcYUFZvJVaC5q3ZdeggAzCAJxScp5KKupaunAArEYmyGYAaqgANgCuZnaOzlpuKpxQGKgAxmYAkgCyHCAARlxwAN70cG00dG1djADWVvZwqNwAJnAAbulZA6hQZtwQ8BNpwMNsHMOt3cZdcBDcHABccABKHKXQwwA8logANHCpmRwAfOQ7HZttjLrAA8MQHHs3AA5PAAO7QHpwDjAXRcT4MbZdGAQo4tHY7AR9RBHG6SI6PLJvLoAXzIZKolGE1OElLgFQAypSabTCGgAHSlWZrCr2S7VWoNKDPAAUAEo3JQqTS6QBRACKAFUAIKqJlSlmJIic7mcWUARwy6T5AvqXFFEooGplUpOyoAcgARADyVWZMrZqB1HDWxyG-xA-JqZuF4sl0updOVDIZsuOABVhAz48cKvaAOIVABiAE13ZHPd61sr7PYuDAGU4XMAMIgg4LzWGrRHabaAFIM532uAMgDCAAlZVVlfnWcgOagwGBlqU2MA9pcBKahZJ7nhUAArMZ4C3kIA

💻 Code occuring the bug

import typia from "typia";

/**
 * @pattern ^[a-z_]+$
 * @minLength 3
 */
type Key = string;

/**
 * @pattern ^[0-9_]+$
 * @minLength 5
 */
type Value = string;

interface IMember {
    /**
     * keys and values are not validated
     */
    one: Record<Key, Value>;
    /**
     * this doesn't work either
     */
    two: {
        [key: Key]: Value;
    }
}

typia.createIs<IMember>();
@samchon
Copy link
Owner

samchon commented Jul 31, 2023

It is a bug of playground. No problem in the real library.

@samchon samchon self-assigned this Jul 31, 2023
@samchon samchon added the documentation Improvements or additions to documentation label Jul 31, 2023
@samchon samchon added this to To do in Documentation via automation Jul 31, 2023
Documentation automation moved this from To do to Done Jul 31, 2023
@samchon
Copy link
Owner

samchon commented Jul 31, 2023

Succeeded to fix the playground bug. Now there would not be such problem.

@rinart73
Copy link
Author

rinart73 commented Jul 31, 2023

I'm still getting the exact same output on the Playground. I also tested in a project and got the some output again.

My project is using Vite so I run the following command typia generate --input src/lib/validation/templates --output src/lib/validation/generated --project tsconfig.json.
I placed the code above in the src/lib/validation/templates/test.ts and this is what was generated:

(input: any): input is IMember => {
  const $join = (typia.createIs as any).join;
  const $io0 = (input: any): boolean => "object" === typeof input.one && null !== input.one && false === Array.isArray(input.one) && $io1(input.one) && ("object" === typeof input.two && null !== input.two && false === Array.isArray(input.two) && $io2(input.two));
  const $io1 = (input: any): boolean => Object.keys(input).every((key: any) => {
    const value = input[key];
    if (undefined === value)
      return true;
    if (RegExp(/(.*)/).test(key))
      return "string" === typeof value;
    return true;
  });
  const $io2 = (input: any): boolean => Object.keys(input).every((key: any) => {
    const value = input[key];
    if (undefined === value)
      return true;
    if (RegExp(/(.*)/).test(key))
      return "string" === typeof value;
    return true;
  });
  return "object" === typeof input && null !== input && $io0(input);
};

As you can see, the @pattern and @minLength were ignored for both Key and Value.

I think I stumbled upon one of your old messages where you said that the TypeScript doesn't allow you to detect type aliases like this and that it will be just replaced with string, not allowing you to parse Key comments.
Is this still an issue? Could it be the reason for why it doesn't work?

/**
 * @minLength 3
 */
type Key = string;

If TypeScript limitation is is the reason of why it doesn't work, perphaps you could allow to add custom comment tags for types other than number, bigint and string? Specifically for object and array? That way, users could write extra checks themselves:

typia.customValidators.insert('keyPattern')('object')((text: string) => {
  const regexp = new RegExp(text);
  return (value: object) => {
    for(const key of Object.keys(value)) {
      if(!regexp.test(key)) return false;
    }
    return true;
  };
});

interface IMember {
  /**
   * @keyPattern ^[a-z0-9]+$
   */
  one: Record<string, string>;
}

@samchon
Copy link
Owner

samchon commented Aug 1, 2023

/**
 * @minLength 3
 */
type Key = string;

Above code does not work because TypeScript compiler API ignores that alias type definition, and consider just as a string type. Therefore, comment tag only works for property type like below.

interface Something {
    /**
     * @minLength 3
     */
    value: string;
}

I haven't considered about the key comment tag like your suggestion, but it seems good idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
No open projects
Development

No branches or pull requests

2 participants