• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Czy TypeScript może się domyślić typu w tym przypadku?

Object Storage Arubacloud
+3 głosów
270 wizyt
pytanie zadane 3 sierpnia 2022 w JavaScript przez rafal.budzis Szeryf (85,260 p.)

Hej chciałbym typować obiekt gdzie wartość każdego klucza powinna być sprawdzana oddzielnie. Wartości w obiekcie są takiego typu: 

interface Values<T extends any> {
    value: T;
    func: (p: T) => void;
    name: string;
}

Wartość value ma być takiego samego typu jak parametr w funkcji func

Chciałbym otypować na raz wszystkie klucze i zastanawiam czy się da. 

const obj: {
    [key: string]: Values<any>;
} = {
    aaa: {
        name: 'aaa',
        value: 123,
        func: (aaa: number) => {
            console.log(aaa);
        },
    },
    bbb: {
        name: 'bbb',
        value: '123',
        func: (aaa: string) => {
            console.log(aaa);
        },
    },
    ccc: {
        name: 'ccc',
        value: '123',
        // tu chce błąd bo value jest string a parametr jest number
        func: (aaa: number) => {
            console.log(aaa);
        },
    },
};


Da się coś w ten deseń zrobić ? Czy musze niestety wymieniać wszystkie klucze osobno? W taki sposób:

const obj: {
    aaa: Values<number>;
    bbb: Values<string>;
    ccc: Values<number>;
} = ...


 

komentarz 3 sierpnia 2022 przez Sadako Obywatel (1,240 p.)

I tak i nie.

Szablon values jest jak najbardziej poprawny i może dawać error gdy użyjesz innych typów.

const stringValue: Values<string> = {
    value:3,
    func : (p: string) => console.log(p),
    name: 'text' 
}

W tym przypadku error bedzie, że do value próbujemy przypisać 3 (number), a typ spodziewany to string. Ten przykład nie przechodzi bo wpisaliśmy Values<string>. Czyli dokładnie wpisaliśmy, że T ma być string. Analogiczny przykład, tylko, że z any przejdzie bez problemu (bo go nie ma :D)

const someValue: Values<any> = {
    value: 3,
    func : (p: string) => console.log(p),
    name: 'strange'
}

To działa jak trzeba. 3 jest number (czyli pasuje do any), funkcja akceptuje string (czyli pasuje do any).

Problem u Ciebie jest, że jawnie wpisałeś/wpisałaś Values<any>. To nic nie da, bo każde property bedzie Value<any>. Z drugiej strony nie możesz wpisać innej nazwy niż any, jeśli mają być tam różne typy, bo jaką ma mieć to nazwę? Value<domyśl się>?

To co próbujesz zrobić wygląda podejrzanie (nie mówie, że takie jest, bo nie wiem co chcesz zrobić - mówie tylko, że tak wygląda). Może jak napiszesz do czego Ci ma służyć ten obj, to ktoś bedzie w stanie Ci doradzić, rozwiązanie problemu w elegantszy sposób.

komentarz 3 sierpnia 2022 przez rafal.budzis Szeryf (85,260 p.)
edycja 3 sierpnia 2022 przez rafal.budzis

Mam sobie system kroków oparty o maszyne w xState i projekt w React. Każdy krok ma przypisane komponenty. Chciałbym dodać nowy komponent powiązany z innym. 

obecnie typ wygląda tak : 

interface ConfigutarionStep {
    label:string;
    isVisible: () => boolean;
    CurrentValueComponent: React.FC<{onClick: () => void}>;
    EditCompoinent: React.FC<{onClose: () => void>;
}

Po zmianach wygląda tak 

interface ConfigutarionStep<DetailsProps extends {[key:string]: any}> {
    label:string;
    isVisible: () => boolean;
    CurrentValueComponent: React.FC<{onClick: () => void}>;
    EditCompoinent: React.FC<{onClose: () => void, onOpenDetails: (props: DetailsProps) => void }>;
    DetailsComponent: React.FC<DetailsProps>;
}

Obecnie obiekt z krokami jest otypowany tak 
 

const STEPS: {
     [key in StepName]: ConfigutarionStep 
} = ...

Nie chciałbym rezygnować z StepName w typie aby TS pilnował tego miejsca podczas dodawania nowego kroku do maszyny stanów. Nie chciałbym też ręcznie wypisywać litani tych typów bo mam ponad 10 kroków. 

EDIT: Narazie wymyśliłem coś takiego 

const STEPS: {
    [key in StepName]: ConfigutarionStep<Props1> | ConfigutarionStep<Props2>;
 = ...

 

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

+1 głos
1 odpowiedź 158 wizyt
pytanie zadane 15 maja 2022 w JavaScript przez Bakkit Dyskutant (7,600 p.)
+1 głos
0 odpowiedzi 153 wizyt
0 głosów
1 odpowiedź 133 wizyt
pytanie zadane 14 grudnia 2019 w JavaScript przez ShiroUmizake Nałogowiec (46,300 p.)

92,543 zapytań

141,384 odpowiedzi

319,488 komentarzy

61,929 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...