0

Given:

const keys = ["A1", "B1", "C1"]

const obj = {}

keys.forEach((key) => {
  const subKey = key[0]
  obj[subKey] = key
})

// obj = { A: A1, B: B1, C: C1 }

Question: For the given scenario above, how do I declare obj's type?

Something like:

type Obj<T in keys> = {
  T: string;
}
5
  • Those are values, not types. That's just an index type { [key: string]: string }. Commented Jan 29, 2018 at 18:06
  • You have an array of string literals and the object should only have props with the same literal type something like type objType = { A1: 'A1', A2: 'A2' } ? Commented Jan 29, 2018 at 18:07
  • @jonrsharpe With { [key: string]: string }, you wouldn't be able to have type completion. Commented Jan 29, 2018 at 18:10
  • What type completion are you expecting? Commented Jan 29, 2018 at 18:12
  • @TitianCernicova-Dragomir Yes. I'm actually using it for React Native where I have an array of strings that I use for Jest (and I do something like fs.readFileSync with those strings), because Jest couldn't handle ImageRequireSource properly. I'm creating an object so that files that import assets could simply import from this sort of central asset reference so they can do <Image source={asset.something} />, that's why I can't have the generic { [key: string]: string }. Commented Jan 29, 2018 at 18:12

1 Answer 1

1

Something close to what you want is possible. Firstly we need to improve on the type of the array. By default the keys array will be of type string[] this does not help us as we need the string literal types for the string values. This helper function will help with that:

function arrayHelper<T extends string>(a: T[]) : T[] {
    return a;
}
var keys = arrayHelper(["A1", "B1", "C1"]); // The type of keys  will be ("A1" | "B1" | "C1")[]

Now that we have the string literal types, we can easily define a type based off them :

var object = (<T extends string>(o: T[]) => 
{
    const obj: { readonly [P in T]: P} = <any>{}
    keys.forEach((key) => {
    obj[key] = key
    });
    return obj;
})(keys);

The type of object will be

var object: {
    readonly A1: "A1";
    readonly B1: "B1";
    readonly C1: "C1";
}

An object that has the original values as keys and the value of the same type as the string literal.

The key is the full value not a substring (it is not possible to perform complex mutations on property names), but this might be something you can live with.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.