0

I'm trying to extract the type of a generic but without having access to it. So I can't use Extract.

import { Feather } from '@expo/vector-icons'

// The type is the following but isn't exported
const Feather: Icon<"crosshair" | "database" | "disc" | "zap" | "droplet" | "sun" | "wind" | "feather" | "link" | "search" | "image" | "menu" | "radio" | "key" | "code" | "map" | "video" | "circle" | ... 267 more ... | "zoom-out", "feather">

// ... how to get it icon list enum?

I'm trying to get a type with "crosshair" | "database" | "disc" | "zap" ...

I also tried this other answer

type TypeOfFeather = typeof Feather
type extractGeneric<T> = T extends TypeOfFeather <infer X> ? X : never

Which obviously doesn't work because the TypeOfFeather is not a generic. I'm quite a beginner at Typescript so I don't really know how to figure this out.

Cohars
  • 3,822
  • 1
  • 29
  • 50

1 Answers1

0

It strikes me as a bit odd that you talk about Feather as a type when in your example it's actually a variable, but you were almost there (playground):

type Icon<T> = {
  _: T;
};

declare const Feather: Icon<"a" | "b">;

// If Feather is actually a type and your example was wrong, just drop the "typeof".
type Result = typeof Feather extends Icon<infer U> ? U : never; // "a" | "b"

On a side note, it would be very helpful to us and thus directly beneficial to you if you provided fully working, minimal examples which include all relevant type definitions (or stubs thereof). Likewise, you didn't actually give the expected outcome (only a vague description thereof), which forces us to guess/assume what you are looking to do; saying "I'm looking to get "a" | "b"" would go along way here.

Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100
  • Indeed I wrote my question a bit too quickly, what I tried to do was indeed to extract the code from `type TypeOfFeather = typeof Feather` and not the variable itself. I also improved the expected outcomes part like you suggested. Thanks for the great suggestions. I thought your answer was good but it doesn't work in my case. I'll try to figure out what's going wrong a improve my question – Cohars May 01 '21 at 18:48
  • The thing is that the package does not exports any types (`Icon` nor the complete list). So I can't do `typeof Feather extends Icon` maybe i'm just stuck, and I should import the `Icon` from `react-native-vector-icons` (which `@expo` simply wraps – without exporting the types..) but it would mean to maintain one more dependency. I'm still interested in a possible answer from a purely theoretical point of view though. – Cohars May 01 '21 at 18:53
  • Looking at the library, you could probably use `keyof Feather['glyphMap']` as well. You can also declare a "shimmed" `Icon` type yourself (TS is structural, not nominal). I think apart from these your options are getting thin. – Ingo Bürk May 01 '21 at 18:59
  • Indeed I so that 'glyphMap` was available but it didn't trigger me... my bad. So `keyof typeof Feather['glyphMap']` does the job Thanks a lot Marking your answer as accepted even if the answer is actually in the comments – Cohars May 01 '21 at 19:09