#Does this typescript function require an as const in its implementation?

1 messages · Page 1 of 1 (latest)

mental fog
#

This snippet ( https://www.typescriptlang.org/play?#code/C4TwDgpgBAggQlAvFA3gQwFxQIwBooBGW2AvgLABQUUAPqplAEz5FPlW31YDMLPJAbkqUAZgFcAdgGNgASwD2EqGgAq8uAAo0ANTQAbMRCzwA2gHI0ZgLoBKY3HMFrqStQBOEYGLdKA9L6gAfmDKdkpVdQ0ABhsofygINzd5N3C1TWxYxGycIQoIzUYsnMY8go1uYuRuMvSNABZY+MTktyA ) shows what I'm trying to achieve and where I'm stuck:

type AB = {a: 1, b: 1}
  | {a: 2, b: 2}
  | {a: 3, b: 3};

function aToB(aValue: AB['a']): AB['b'] {
  return // ???
}

aToB(0) // error
aToB(1) === 1;
aToB(2) === 2;
aToB(3) === 3;
aToB(4) // error

I'm trying to figure out how I can implement the aToB function. I've tried these things but I can't get them to compile:

    function aToB<T extends AB>(aValue: T['a']): T['b'] {
      return AB[aValue]; // 'AB' only refers to a type, but is being used as a value here.
    }

While that error makes sense to me, I'm not sure how to work around it unless I use an as const array ( https://www.typescriptlang.org/play?#code/MYewdgzgLgBAhgIxgXhgbQN5wFwwIwA0MCueAvgLABQMMRWuATESTI5TXTAzAMwu5eZALrwIMUJCgBuatSgBPAA4BTGAEEAQihgAKRapAAzeAgCUaMAFcAtghUAnYbKrUjVsMCgBLcPAAqIJoAPP4wKgAeUCpgACbiWgB8unAAanAANlYquP5oAORw cJmuQUIxdzUtA4qUFYOYKYAdEbecbq6EWYoiTARzXAoyKhpmdlmAITNCC4c1HCBmroADD0A9OvhDg4gDgtLung9I6h4LotBuownI2wXh7y3qLwPVwAsG1uOuw5AA ):

const ab = [{a: 1, b: 1}
  , {a: 2, b: 2}
  , {a: 3, b: 3}] as const;

type AB = (typeof ab)[number];

function aToB<T extends AB>(aValue: T['a']): T['b'] {
  return ab.find((x) => x.a === aValue)!.b;
}

aToB(0) // error
aToB(1) === 1;
aToB(2) === 2;
aToB(3) === 3;
aToB(4) // error

Is this a scenario where you need to define an as const in order to implement this function? Or, is there a way to implement it in another way?

granite ermine
#

Is this a scenario where you need to define an as const in order to implement this function?
More or less - you can't use the type directly, there needs to be some runtime support.

mental fog
#

okay that's good to know

#

I have a follow-up question: what if you want the value of b to be an interface?

granite ermine
#

If you're going to use an array it needs to be const to preserve the literal values, though I probably wouldn't use an array.

mental fog
granite ermine
#

Here's what I'd realistically do:

const aToBMap = { 
  1: 1,
  2: 2,
  3: 3
}
type AToBMap = typeof aToBMap

function aToB<A extends keyof AToBMap>(aValue: A): AToBMap[A] {
  return aToBMap[aValue]
}
#

No, that was in reply to the general concept.

mental fog
granite ermine
mental fog
#

hm, I don't think that'll work for me because your aToBMap has a real implementation on the right-hand side. Let me show you the type of thing I'm trying to do

#

actually let me ping you in another question of mine since I think this one has been answered by you. Thanks again