Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

284
Visualizações
Typescript (React) function declaration correct but paramters show "any" type

I built a Select component in react that is fully typed and I now added a multiple prop to it, that will change the typing of the value and the onChange callback to be of type Array<T> What the multiple prop does is it uses what I believe is called a Distributive Conditional to determine the type of both value and onChange of the Component's props like this:

interface SelectBaseProps<T extends SelectValue = string> {
  options: SelectOption<T>[];
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  searchable?: boolean;
}

export type SelectProps<T extends SelectValue, TMultiple extends boolean = false> = SelectBaseProps<T> &
  (TMultiple extends false
    ? {
        multiple?: TMultiple;
        value: T;
        onChange: (value: T) => void;
      }
    : {
        multiple?: TMultiple;
        value: T[];
        onChange: (value: T[]) => void;
      });

Where SelectValue just limits the values to be of type string or number for now. I know, not the prettiest implementation but this is already after some iterations of debugging. And then the select component itself is basically just

export default function Select<T extends SelectValue, TMultiple extends boolean = false>(...) {...}

Now, on first sight this seems to work just fine! If I use this in a test component like this:

function SelectTest() {
  const [val, setVal] = useState<string>();
  const options: SelectOption<string>[] = [
    { label: 'Option 1', value: '1' },
    { label: 'Option 2', value: '2' },
    { label: 'Option 3', value: '3' },
  ];

  return <>
      <Select value={val} options={options} onChange={(x) => console.log(x)} />
      {/* However, this works! */}
      <Select value={val} options={options} onChange={setVal} />
    </>;
}

and hover over the onChange prop, it clearly says that the prop of the onChange callback is of type string. If I change the code and make value be an array, the onChange value is also of type array. But for some reason, the type is not infered in the function passed into the callback and typescript complains that Parameter 'x' implicitly has an 'any' type.

So my question: Why is typescript not able to infer the type here, even though the function is typed correctly and can infer the type even for custom string types?

It could be related to my tsconfig configuration, so I added it in the reproduction stackblitz:

https://stackblitz.com/edit/react-ts-wuj3yu?file=Select.tsx,tsconfig.json

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Take a look: https://stackblitz.com/edit/react-ts-agwgkq?file=Select.tsx,App.tsx

I have to refuse of defining so many types/props:

import React, { useState } from 'react';

export type SelectValue = string | number | Array<string> | Array<number>;

type Unwrap<T> = T extends Array<infer R> ? R : T;

export interface SelectOption<T extends SelectValue> {
  label: string;
  value: Unwrap<T>;
}

interface SelectProps<T extends SelectValue> {
  options: SelectOption<T>[];
  value: T;
  onChange: (value: T) => void;
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  searchable?: boolean;
}

export function Select<T extends SelectValue>(props: SelectProps<T>) {
  return <div>Dummy Select</div>;
}

...

import * as React from 'react';
import { Select } from './Select';
import './style.css';

export default function App() {
  const [val, setVal] = React.useState<string>('');
  const options = [
    { label: 'Option 1', value: '1' },
    { label: 'Option 2', value: '2' },
    { label: 'Option 3', value: '3' },
  ];
  const [multipleVal, setMultipleVal] = React.useState<Array<string>>([]);

  return (
    <React.Fragment>
      <Select value={val} options={options} onChange={(x) => console.log(x)} /> // x is string
      {/* However, this works! */}
      <Select
        value={multipleVal}
        options={options}
        onChange={(x) => console.log(x)} // x is Array<string>
      />
    </React.Fragment>
  );
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda