-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Operator to produce keys of a type where the properties of that type in those keys match some type #48992
Comments
related: #30728 |
Note to self for future ease of searching: I usually call |
Sure would be nice to see this implemented! The
|
@RobertAKARobin actually that doesn't even work on the base class. class Animal {
breathe() {
console.log(`Ahh`);
}
exec<T extends Record<MethodName, Function>, MethodName extends keyof T>(this: T, methodName: MethodName) {
(this[methodName] as Function)();
}
}
class Cat extends Animal {
a = 1;
constructor() {
super();
this.exec(`breathe`);
}
meow() {
console.log(`Meow`);
}
} |
Another issue that maybe related to this interface Test {
a: boolean;
b?: boolean;
c: undefined;
d?: string;
e: number;
}
interface TestGeneric<T> extends Test {
f: T;
g: T[];
}
type BooleanKey<T, K extends keyof T = keyof T> = K extends any ? T[K] extends (boolean|undefined) ? (T[K] extends undefined ? never : K) : never : never;
type BooleanKeys<T> = {
[K in keyof T]-?: T[K] extends (boolean | undefined) ? (T[K] extends undefined ? never : K) : never;
}[keyof T];
type t1 = BooleanKey<Test>;
type t2 = BooleanKeys<Test>;
type NonNullableBoolOnlyFields<T> = {
[K in BooleanKeys<T>]-?: boolean;
};
type NonNullableBools<T> = T & NonNullableBoolOnlyFields<T>;
type Test1 = NonNullableBools<Test>
type Test2<T> = NonNullableBools<TestGeneric<T>>
type Field = 'e';
function test1(p1: Test1[Field]): number {
const result: number = p1;
return result;
}
function usetest1() {
return test1(10);
}
function test2<T>(p1: Test2<T>[Field]): number {
const result: number = p1;
return result;
}
function usetest2<T>() {
return test2<T>(10);
} |
I'm having trouble trying to get the following to produce the correct type - is this the same issue as this discussion? // This type allows defining "enums" which are either string values or are a single key with an embedded value (similar to Rust enums)
export type ValueEnum<K extends string = string, V = any> = {
[P in K]: Record<P, V> & Partial<Record<Exclude<K, P>, never>> extends infer O
? { [Q in keyof O]: O[Q] }
: never;
}[K];
export type Enum<T = any, K extends string = string> = K | ValueEnum<K, T>;
// This is an example of how you'd define an enum
export type ValidState<T> = ("unknown" | {
"valid": T;
} | {
"invalid": string;
} | "loading");
// I'm attempting to have unwrapEnum access embedded values directly (or return undefined if the enum is not of type K or type K is not an embedded type)
export type EnumData<T extends Enum> = T extends object ? T : never;
export type EnumDataKeys<T extends Enum> = T extends object ? keyof T : never;
export const unwrapEnum = <T extends Enum, const K extends EnumDataKeys<T>>(
enm: EnumData<T> | string,
type: K
) => {
if (typeof enm === "string") {
return undefined;
}
return enm[type];
};
// Example of code that uses the above ValidState code
export type InnerType = {
test: string;
};
const test: ValidState<InnerType> = { valid: { test: "FHHII" } };
// This produces InnerType
const validInfo1 = unwrapEnum(test, "valid");
const getValue = (): ValidState<InnerType> => {
return { valid: { test: "FHHII" } };
}
// This produces "unknown"
const validInfo2 = unwrapEnum(getValue(), "valid"); |
Suggestion
π Search Terms
keyof property keysOfType
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
We frequently get people writing definitions to produce the keys
K
of an object typeO
whereO[K] extends T
. Let's call this operationKeysOfType<O, T>
. Varying userland definitions includeThese userland definitions work in concrete cases, but can't be used to write generic functions:
We could add a new type operator or intrinsic alias
KeysOfType<T, P>
that returns allkeyof T
K
such thatT[K] extends P
. When this type indexes a generic object of typeT
, we can then know thatT[KeysOfType<T, P>]
is assignable toP
. In non-generic positions, this can be immediately resolved the same way as the userland definition.π Motivating Example
See
getString
aboveπ» Use Cases
This is a frequent complaint; need link more inbound issues here
#48989
The text was updated successfully, but these errors were encountered: