简体   繁体   English

Typescript:function,枚举类型的参数分配给回调,参数类型为字符串

[英]Typescript: function with argument of enum type assigned to callback with argument type of string

I have a dropdown component with a callback onSelect:(option: string) => void我有一个带有回调onSelect:(option: string) => void的下拉组件

I'm using it as a sort picker in one application, where the options are of enum type:我在一个应用程序中将它用作排序选择器,其中选项是枚举类型:

enum SORT_OPTIONS {
  LATEST = 'LATEST',
  OLDEST = 'OLDEST'
}
const onSortSelect = (val: SORT_OPTIONS) => {...}
<MyDropdown onSelect={onSortSelect} ... />

And typescript complains: typescript 抱怨:

Type '(val: SORT_OPTIONS) => void' is not assignable to type '(option: string) => void'.
  Types of parameters 'val' and 'option' are incompatible.
    Type 'string' is not assignable to type 'SORT_OPTIONS'.  TS2322

It's a bit counter-intuitive but makes sense, since in MyDropdown a string option will be passed to the onSortSelect callback, which requires an enum value.这有点违反直觉,但很有意义,因为在MyDropdown中,一个字符串option将传递给onSortSelect回调,这需要一个枚举值。

Question is what is the best way to fix the types here?问题是在这里修复类型的最佳方法是什么? IMO both functions are typed correctly, onSelect should accept any string since MyDropdown can be used in any context. IMO 两个函数都输入正确, onSelect应该接受任何字符串,因为MyDropdown可以在任何上下文中使用。 onSortSelect should only accept SORT_OPTIONS . onSortSelect应该只接受SORT_OPTIONS

Currently I'm casting the type of onSortSelect: <MyDropdown onSelect={onSortSelect as (val:string) => void}... /> but it feels quite verbose目前我正在投射 onSortSelect 的类型: <MyDropdown onSelect={onSortSelect as (val:string) => void}... />但感觉很冗长

Your callback deals with onSelect:(option: string) => void您的回调处理onSelect:(option: string) => void

This means that it passes any string to the handle, like: hello , test , and so on.这意味着它将任何字符串传递给句柄,例如: hellotest等。

But your const onSortSelect = (val: SORT_OPTIONS) => {...} expects only subset of strings: LATEST, OLDEST.但是您的const onSortSelect = (val: SORT_OPTIONS) => {...}只需要字符串的子集:LATEST、OLDEST。

So, TypeScript warns you that you can't pass the whole set to a function that expects subset.因此,TypeScript 警告您不能将整个集合传递给期望子集的 function。

To fix the issue, you need to update your onSelect handler to:要解决此问题,您需要将onSelect处理程序更新为:

onSelect:(option: SORT_OPTIONS) => void

I managed to fix the types with Generics, no typescript error我设法用 Generics 修复了类型,没有 typescript 错误

enum SORT_OPTIONS {
  NEWEST='1',
  OLDEST='2'
}

interface DropdownProps<T extends string> {
  onSelect: (val: T) => void;
  options: T[];
}

const Dropdown = <T extends string>(props: DropdownProps<T> & {children?: React.ReactNode}) =>{
  const {onSelect, options} = props;
  return <select onChange={(evt) => onSelect(evt.target.value as T)}>
    {options.map(option => <option>{option}</option>)}
  </select>

};



const TestComp:React.FC = () => {
  const onSelect = (val: SORT_OPTIONS) => {
    switch (val) {
      case SORT_OPTIONS.OLDEST:
        console.log('old');
        break;
      case SORT_OPTIONS.NEWEST:
        console.log('new');
        break;
    }
  };
  const onSelect2 = (val: string) => {
    console.log(val);
  };
  return <>
    <Dropdown
      options={[SORT_OPTIONS.NEWEST, SORT_OPTIONS.OLDEST]}
      onSelect={onSelect}
    />
    <Dropdown
      options={['aaa', 'bbb']}
      onSelect={onSelect2}
    />
    </>
};

Note that注意

  1. I can't type Dropdown with the regular React.FC , see the discussion here: How to use generics in props in React in a functional component?我无法使用常规React.FC键入Dropdown ,请参阅此处的讨论: 如何在功能组件中的 React 中的道具中使用 generics?
  2. I have to do a type casting to the Generic type.我必须对通用类型进行类型转换。

Please comment if you find a different conclusion from the link.如果您从链接中发现不同的结论,请发表评论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 function 的类型推断作为 Typescript 中的参数 - Type inference of function as argument in Typescript 什么打字稿类型用于函数参数? - What typescript type use for function argument? 正确输入 function object 参数 TypeScript - Properly type function object argument TypeScript TypeScript - “字符串”类型的参数不可分配给“字符串”类型的参数 - TypeScript - Argument of type 'String' is not assignable to parameter of type 'string' Typescript:'(i: string[]) =&gt; any[]' 类型的参数不可分配给'string[]' 类型的参数 - Typescript: Argument of type '(i: string[]) => any[]' is not assignable to parameter of type 'string[]' ReactJS Typescript 类型的参数 '{ keyPrefix: string; }' 不可分配给字符串类型的参数 - ReactJS Typescript Argument of type '{ keyPrefix: string; }' is not assignable to parameter of type string React,typescript - 'string | 类型的参数 null' 不能分配给“字符串”类型的参数 - React, typescript - Argument of type 'string | null' is not assignable to parameter of type 'string' 'string' 类型的参数不可分配给 typeScript 中的 'never' 类型的参数 - Argument of type 'string' is not assignable to parameter of type 'never' in typeScript React Typescript - 'string' 类型的参数不可分配给 useState 中的类型参数 - React Typescript - Argument of type 'string' is not assignable to parameter of type within useState typescript 3.6 中的默认类型参数和默认参数 - default type argument and default argument in typescript 3.6
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM