关于TypeScript的if策略问题

140 阅读1分钟

起因

今天有群友发现了一个这样的问题他写了下面这段代码。

const FormMapObj = {
  select: (a: string) => {
    return '1';
  },
  editer: (a: boolean) => {
    return false;
  },
  autoCompleteGoogle: (a: number) => {
    return 1;
  },
};

export type InputType = keyof typeof FormMapObj;

const getField = <T extends keyof typeof FormMapObj>(type: T) => {
  return FormMapObj[type];
};

let data: { type: InputType }[] = [
  {
    type: 'select',
  },
  {
    type: 'editer',
  },
  {
    type: 'autoCompleteGoogle',
  },
];

const main = () => {
  let arr = data.map((item) => {
    if (item.type === 'autoCompleteGoogle') {
      const func = getField(item.type)
      func(1)
    } else if (item.type === 'editer') {
      const func = getField(item.type)
      func(false)
    } else {
      const func = getField(item.type)
      func("1")
    }
  });
};

这里有一个问题为什么不能把const func = getField(item.type)抽离出来,我的func和type是一一对应的。

分析

const main = () => {
  let arr = data.map((item) => {
   const func = getField(item.type)
    if (item.type === 'autoCompleteGoogle') {
      func(1)
    } else if (item.type === 'editer') {
      func(false)
    } else {
      func("1")
    }
  });
};

这段代码会报错func的参数报错,这里就很奇怪了我们明明type和func是一一对应的为什么还会报错呢。在这里我们忽略了一个问题在idea看来type和func是没有强绑定关系的,如果我们做了一个这样的操作。

const main = () => {
  let arr = data.map((item) => {
   const func = getField(item.type)
   item.type = ''
    if (item.type === 'autoCompleteGoogle') {
      func(1)
    } else if (item.type === 'editer') {
      func(false)
    } else {
      func("1")
    }
  });
};

假如说我们给type和func添加一个强绑定关系,创建一个对象{ type:k, func:typeof FormMapObj[k] }

const FormMapObj = {
  select: (a: string) => {
    return '1';
  },
  editer: (a: boolean) => {
    return false;
  },
  autoCompleteGoogle: (a: number) => {
    return 1;
  },
} as const;

export type InputType = keyof typeof FormMapObj;

const getField = <T extends keyof typeof FormMapObj>(type: T) => {
  return FormMapObj[type];
};

let data: { type: InputType }[] = [
  {
    type: 'select',
  },
  {
    type: 'editer',
  },
  {
    type: 'autoCompleteGoogle',
  },
];

type TypeByObj = {[k in keyof typeof FormMapObj]:{
  type:k,
  func:typeof FormMapObj[k]
}}[keyof typeof FormMapObj]

const main = () => {
  let arr = data.map((item) => {
    let funcItem = {
      type: item.type,
      func: getField(item.type),
    } as TypeByObj
    if (funcItem.type === 'autoCompleteGoogle') {
      funcItem.func(1)
    } else if (funcItem.type === 'editer') {
      funcItem.func(false)
    } else {
      funcItem.func("1")
    }
  });
};

通过这种强绑定关系就可以解决了这个报错。