Reputation: 339
This is my code:
type FormState = "email" | "password" | "whatever";
const f = <
T extends FormState,
K extends keyof T
>(
fieldName: K,
fieldValue: T[K],
hasErrors?: boolean
) => {}
f.bind(null, "email"); // <-- This gives error
I'm unable to change neither the type nor the function, how can I use bind here?
This is a link to the typescript playground.
The log of the error is:
No overload matches this call.
Overload 1 of 6, '(this: (this: null, arg0: number | ... 42 more ... | "padEnd", fieldValue: string | ... 42 more ... | ((maxLength: number, fillString?: string | undefined) => string), hasErrors?: boolean | undefined) => void, thisArg: null, arg0: number | typeof iterator | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | ... 31 more ... | "padEnd"): (fieldValue: string | ... 42 more ... | ((maxLength: number, fillString?: string | undefined) => string), hasErrors?: boolean | undefined) => void', gave the following error.
Argument of type '"email"' is not assignable to parameter of type 'number | unique symbol | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 28 more ... | "padEnd"'.
Overload 2 of 6, '(this: (this: null, ...args: "email"[]) => void, thisArg: null, ...args: "email"[]): (...args: "email"[]) => void', gave the following error.
The 'this' context of type '<T extends FormState, K extends keyof T>(fieldName: K, fieldValue: T[K], hasErrors?: boolean | undefined) => void' is not assignable to method's 'this' of type '(this: null, ...args: "email"[]) => void'.
Types of parameters 'fieldName' and 'args' are incompatible.
Type '"email"' is not assignable to type 'number | unique symbol | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 28 more ... | "padEnd"'.
Upvotes: 0
Views: 291
Reputation: 16147
K extends keyof T
and T extends FormState
mean K
will get 0
, 1
, or 2
... as value.
Then your f
function will look like this:
const f = (fieldName: number, fieldValue: string, hasErrors?: boolean) => {}
// and to bind f you have to bind a number as the second parameter
f.bind(null, 0);
But, I guess it is not what you want, I think you need the fieldName
is FormState
. Just try to update the type of fieldName
to T
instead of K
const f = <T extends FormState, K extends keyof T>(fieldName: T, fieldValue: T[K], hasErrors?: boolean) => {}
f.bind(null, "email");
Upvotes: 1
Reputation: 4213
It looks like you are using the wrong types because you are doing keyof FormState
is the same as doing keyof string
which just gives you the string methods. Perhaps you should limit your function to a single parameter or enhance your types?
type FormState = "email" | "password" | "whatever";
const f = <T extends FormState>(fieldName: T, hasErrors?: boolean) => {}
f.bind(null, "email");
Upvotes: 0