-
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
Parameter of type 'K extends FunctionPropertyNames<T>' is always a union type and not restricted to the string literal passed to function #25215
Comments
Two possible workarounds and you can pick your favorite interface I {
property1: string;
method1(): void;
method2(s: string): number;
}
type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T];
function getProperty<T, K extends keyof T>(obj: T, propName: K & FunctionPropertyNames<T>): T[K] {
return obj[propName];
}
declare const i: I;
const m1 = getProperty(i, "method1");
const m2 = getProperty(i, "method2");
const p1 = getProperty(i, "property1"); or interface I {
property1: string;
method1(): void;
method2(s: string): number;
}
type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T];
function getProperty<T, K extends string & FunctionPropertyNames<T>>(obj: T, propName: K): T[K] {
return obj[propName];
}
declare const i: I;
const m1 = getProperty(i, "method1");
const m2 = getProperty(i, "method2");
const p1 = getProperty(i, "property1"); |
Another workaround is to simply change type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T] & string; The intersection with |
Thank you very much for the answers. @ahejlsberg Could you explain why the checker doesn't do that without the |
I'm also curious why |
TypeScript Version: 2.8.3 and 2.9.1 (I think. The actual version in playground)
Code
The next code works as expected.
But I want to restrict the
key
parameter infoo
to just functions.Since #21316, and as an example on that PR, we can use something like
FunctionPropertyNames
.Expected behavior:
f5
andf6
inferred to() => void
and(a: string) => number
, respectively, without need a type assertion (pretty much as the first snippet).Actual behavior:
f5
andf6
are both inferred to() => void | (a: string) => number
, which is very odd since I'm passing a literal string.Playground link
Playground link
Related Issues:
Maybe #24080 (but that seems related to the
keyof T
~string | number | symbol
issue and my example fails with TS 2.8)The text was updated successfully, but these errors were encountered: