Home > OS >  Generic typescript function to validate that the key of an object is a string
Generic typescript function to validate that the key of an object is a string

Time:03-31

Here is the function I'd like to write, and I cannot quite get the generic to work.

As you can see - I'd like to return that T[K] is definitely a string - the point is to be able to use it

a = {key: "unknown type"};

if (!validateRequiredStringKey(a, "key")) {
    return
}
// Here we should know that a.key is a string

funcThatTakesAString(a.key);
export const validateRequiredStringKey = <
  T,
  K extends keyof T & (string | number)
>(
  obj: T,
  key: K
): obj is T & { [K]: string } => {
  const v = obj[key];

  if (!(typeof v === "string")) {
    throw new ValidationError(`${key} is not a string`);
  }
  if (v === "") {
    throw new ValidationError(`${key} is empty`);
  }
  return true;
};

The errors from tsc are

src/domain/validations/utils.ts:12:17 - error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.

12 ): obj is T & { [K]: string } => {
                   ~~~

src/domain/validations/utils.ts:12:18 - error TS2693: 'K' only refers to a type, but is being used as a value here.

12 ): obj is T & { [K]: string } => {

CodePudding user response:

I haven't thoroughly checked the definition of validateRequiredStringKey, but you can make it work by replacing { [K]: string } with {[Key in K]: string}, or just Record<K, string>.

TypeScript playground

  • Related