网站搜索

typescript - 将对象键与返回函数的返回值关联


// try trim string
export default function safeTrim(value: unknown): string | undefined {
  if (typeof value === 'string') {
    return value.trim();
  }
  return undefined;
}

// index and items used for array
type Validator<T extends object> = (item: T, index?: number, items?: T[]) => null | { [key in keyof T]: string[] };

export function emptyValidator<T extends object>(keyName: keyof T): Validator<T> {
  return (item) => {
    if (!safeTrim(item[keyName])) {
      // @ts-ignore
      const error: { [key in keyof T]: string[]} = { // line 18
          [keyName]: [`Field should not be empty`],
        };
        return error;
    }
    return null;
  };
}

// ======= examples usage ======== 

const testObject = {
    propThatReturnNull: 'some string',
    propThatReturnError1: '',
    propThatReturnError2: undefined,
    propThatReturnError3: null
} as const;

emptyValidator('propThatReturnNull')(testObject); // should return null
emptyValidator('propThatReturnError1')(testObject); // should return {propThatReturnError1: [`Field should not be empty`]}
emptyValidator('propThatReturnError2')(testObject); // should return {propThatReturnError2: [`Field should not be empty`]}
emptyValidator('propThatReturnError3')(testObject); // should return {propThatReturnError3: [`Field should not be empty`]}

在第18行我得到错误 类型 ‘{ [x: string]: string[]; }’ 不能分配给类型 ‘{ [key in keyof T]: string[]; }’。

我预期 keyName 的类型是 "keyof T" 而不是 "string"。

我如何匹配链接对象的键和返回对象的键类型?

TypeScript 播放场示例

答案#1

类型 { [key in keyof T]: string[] } 是一个映射类型,TypeScript 无法在函数实现中自动推断它,所以你必须显式地为返回值指定类型:

export function emptyValidator<T extends object>(keyName: keyof T): Validator<T> {
  return (item) => {
    if (!safeTrim(item[keyName])) {
      return {
          [keyName]: [`Field should not be empty`],
        } as { [key in keyof T]: string[] };
    }
    return null;
  };
}