-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
keyof to produce a runtime array #13267
Comments
Perhaps this could be generalized to turning a union of literal types (as |
in what order should these properties go? |
I for one don't care; alphabetical, as-declared, officially-undefined, I just want it to be complete. |
i think it should be a codefix (refactoring) rather than a runtime facility:
|
It's better than nothing but it definitely doesn't do everything I would have liked. For example, in my testing example, the entire point is ensuring complete coverage of the union for the test case. If a new item is added to the union, that array is still a valid array of items from that union, but it is no longer "complete"—some values from the union are not represented in the array. |
on the other hand, the fact that there is no way to know the order of names in which they will be listed is disturbing in a meanwhile there is a hack:
although it's not perfect either: #12253 (comment) |
That hack does nothing for the case of a union that isn't derived from |
that wouldn't that easy function keys<T>(): (keyof T)[] {
return keyof T;
}
console.log(keys<{ a: number; }>());
console.log(keys<{ c: bool; }>()); what would it emit? Consider:
|
a better hack that is almost to the point (yet has problems with unions) interface Foo {
kind: 'a';
value: number;
}
interface Baz {
kind: 'b';
text: string;
}
type Bar = Foo | Baz;
type Names<T> = { [P in keyof T]: P; }
function toKeysBySample<T>(names: Names<T>): (keyof T)[] {
return Object.values(names);
}
toKeysBySample<Bar>({ kind: 'kind', text: 'text' }); |
@Igorbek has a good point, if we remember that any type driven emit is taboo |
As noted by @Igorbek and @Aleksey-Bykov, type directed emit is something that violate the TS goals of a fully erasable type system. Moreover, a For both reasons, this is out of scope for the TypeScript project at the time being. |
The second reason is the entire reason I wanted this feature. I don't want the complete runtime list. I want strictly and only the ones listed in the interface. As for the first, I guess I just don't see why that should be a goal at all. |
Probably a duplicate or at least a sub-issue of #1549. |
This is possible with custom transformers introduced by #13940. |
What about generating an enum at compile-time? type A = { x: number, y: string };
enum B = keyof A; // as A exists right now during compilation
for (var enumMember in B) {
console.log("enum member: ", enumMember);
} which would write: 0
1
x
y and would have the following JS code: (function (B) {
B[B["x"] = 0] = "x";
B[B["y"] = 1] = "y";
})(B = exports.B || (exports.B = {})); As to what order... doesn't matter to me. I just want this to validate a JSON config file against a TypeScript Interface without requiring something like |
Put simply, I'd like a variant of keyof which produces the keys at runtime. E.g.,
In this case
x
should be["prop1", "prop2"]
.I've seen a few cases where people have tried to use
keyof
in somewhat-similar fashions, but they all wanted the actual keys present in the object at runtime. I however very explicitly want to ignore any properties present in any hypothetical runtime Foo objects that are not present in the interface.Should permit generic parameters as the type.
The text was updated successfully, but these errors were encountered: