Olivier Lance
Olivier Lance

Reputation: 1748

Infer tuple from const array of numbers?

I'm having troubles finding correct keywords to express what I'm looking for; feel free to edit my title so it makes more sense.

I'd like to know if it's possible with TypeScript to achieve something like the below "pseudo-TS"?

It doesn't work, but I wish it did behave as I say in the comments:

type Constraint<T extends number> = {    // T => 3 | 4 ?
  [k in T]: { min: number, max: number }
}

type Data<K extends number[] = []> = {  // is there anyway to use `Data` *without* its param by 
  indexes: K,                          // asking TS to infer K from `indexes`?
  constraints: Constraint<typeof K>
}

const d: Data = {            // Data<3 | 4> is inferred from indexes
  indexes: [3, 4],           // being given a const array `[3, 4]`
  constraints: {
    3: { min: 0, max: 120 },
    4: { min: 10, max: 20 },
    10: { min: -3, max: 3},  // -> Would error, since 10 is not in `indexes: [3, 4]`
  }
}

There are a lot of missing pieces for me there, and as I said, not knowing which terms to search for, I'm having trouble deciding whether it's definitely not feasible...

Since everything in what I want to do stems from the value of the indexes array, I'm guessing it shouldn't be possible. But I have seen things such as:

[1, 2, 3] as const // => 1 | 2 | 3

so I wonder if that could be used in my situation in any way?

Upvotes: 0

Views: 85

Answers (1)

martindelophy
martindelophy

Reputation: 71

this may help you solve problem

type Constraint<T extends number> = {    // T => 3 | 4 ?
  [k in T]: { min: number, max: number }
}

type Data<T extends ReadonlyArray<number>, K extends number> = {  // is there anyway to use `Data` *without* its param by 
  indexes: T,                          // asking TS to infer K from `indexes`?
  constraints: Constraint<K>
}

const indexesNum =  [3, 4] as const ;

type GetItem<T> = T extends ReadonlyArray<infer I> ? I: never;

const d: Data<typeof indexesNum, GetItem<typeof indexesNum>> = {            // Data<3 | 4> is inferred from indexes
  indexes: indexesNum,           // being given a const array `[3, 4]`
  constraints: {
    3: { min: 0, max: 120 },
    4: { min: 10, max: 20 },
    10: { min: -3, max: 3},  // -> Would error, since 10 is not in `indexes: [3, 4]`
  }
}

Upvotes: 1

Related Questions