4

I have this Identity interface

export interface Identity {
    username: string;
    name: string;
    surname: string;
    roles: string[];
}

and I want to get an array of Strings at runtime with all its keys.

const keys: string[] = ["username", "name", "surname", "roles"];

If it were a class, it would have been easy enough using the constructor (as suggested here).

class Identity {
    constructor(
        readonly username?: string,
        readonly name?: string,
        readonly surname?: string,
        readonly roles?: string[]
    ) {}
}

const properties: string[] = Object.keys(new Identity());

I have found other similar questions, some about the Keyof Type Operator, with the most relevant being:

In the above questions, however, the result of keyof is only used as a type/value constraint. What about how to get the keys as a String array using the keyof operator? Is this not possible from an Interface definition or for classes too?

TypeScript Custom Transformer

This project, a custom transformer, does exactly what I'm looking for: get the keys of a given Type.

I'm wondering if there is an easier way, possibly using only the keyof operator to get the same result.

1Z10
  • 2,801
  • 7
  • 33
  • 82
  • 4
    At runtime the interface doesn't exist, so you can't get the keys as an array of strings. – jonrsharpe Oct 06 '21 at 10:11
  • Is this the case for a class too? I mean, is it not possible to get the keys as a string array starting from its type only, without the need to create a new instance and pass it to `Object.keys(theTypeInstance);` ? – 1Z10 Oct 06 '21 at 10:21
  • You can get keys only by using `Object.keys`. – captain-yossarian from Ukraine Oct 06 '21 at 10:22
  • 3
    None of the types exist at runtime - they're erased in transpilation, because JavaScript doesn't have them. Classes do exist at runtime, but the type information is erased. Look at what's actually emitted in e.g. https://www.typescriptlang.org/play. – jonrsharpe Oct 06 '21 at 10:22
  • Ok, I get the transpilation process. Here https://github.com/kimamula/ts-transformer-keys there is a TS custom transformer project which does exactly what I'm looking for. I was just wondering if/how could be done without using it but only existing TS operators. – 1Z10 Oct 06 '21 at 10:35
  • Does this answer your question? [Get keys of a Typescript interface as array of strings](https://stackoverflow.com/questions/43909566/get-keys-of-a-typescript-interface-as-array-of-strings) – jonrsharpe Oct 06 '21 at 10:55
  • Sadly not. I've already seen it and added to the body of my question as a reference. The first answer proposes a custom transformer, also linked by me above, which I do not want to use. I would like to use only pure TypeScript operators such as Keyof. The second answer uses keyof bu only as a type for compile time validation, instead of the actual keys array as strings. the third answer suggests to use a class and an Object instance with Object.keys()... Moreover I'm working on an old project with just TypeScript 2.6.x – 1Z10 Oct 06 '21 at 11:02
  • The fact that you don't _like_ the answers isn't really relevant - those are the options for various use cases, and a "pure TypeScript" version is [out of scope](https://github.com/microsoft/TypeScript/issues/13267#issuecomment-270251290) for that project. – jonrsharpe Oct 06 '21 at 11:07
  • Thanks for the ref. How explained in the [comment below](https://github.com/microsoft/TypeScript/issues/13267#issuecomment-270336162) it may still be useful to strictly get the fields defined by the interface, instead of possible additional properties available at runtime. – 1Z10 Oct 06 '21 at 11:22

1 Answers1

0

For example interface like this:

export interface Identity {
 username: string;
 name: string;
 surname: string;
 roles: string[];
}

And you want to extract keys. there is no direct way to do it but you can do this:

const extractedKeys: Array<keyof Identity> = 'username','name','surname']; 

The output should be like this array Link:

["username", "name", "roles"]
Akib
  • 304
  • 2
  • 9
  • Link: https://stackblitz.com/edit/typescript-pccdxd?file=index.ts – Akib Aug 22 '23 at 11:05
  • Thank you for contributing to the Stack Overflow community. This may be a correct answer, but it’d be really useful to provide additional explanation of your code so developers can understand your reasoning. This is especially useful for new developers who aren’t as familiar with the syntax or struggling to understand the concepts. **Would you kindly [edit] your answer to include additional details for the benefit of the community?** – Jeremy Caney Aug 23 '23 at 02:37