I'm having trouble understanding the following lambda function definition in TypeScript. It could be a beginner question.
type P = { id: string }
type F = <T>(x: T) => string
const f: F = (x: P) => x.id
f({ id: 'abc' }
However, I keep getting the error message below:
Type '(x: P) => string' is not assignable to type 'F'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'P'.
Update #1
I would like to provide some context for why I need a generic function. The purpose is to verify an input object, and each path of the object can be configured for verification as shown below:
type Option = { path: string; isVerified: <T>(t: T) => boolean }
const verify = (obj: any, options: Option[]): boolean => {
const results = options.map(option => {
const { path, isVerified } = option
return isVerified(obj[path])
})
return results.every(x => x)
}
type A = number
type B = string
const obj = { a: 1 as A, b: 'abc' as B }
verify(obj, [
{ path: 'a', isVerified: (x: A): boolean => x > 0 },
{ path: 'b', isVerified: (x: B): boolean => x.startsWith('a') }
])
Update #2
Thank you for the initial answer, it resolved the issue mentioned in Update #1
. However, the problem described in Update #1
is actually simplified. In reality, the path
within the Option
type could be either a string
or a RegExp
, which makes the code using Paths[K]
invalid, as seen below:
type Option = { path: string | RegExp; isVerified: <T>(t: T) => boolean }
const verify = (obj: any, options: Option[]): boolean => {
const results = Object.keys(obj).map(k => {
const verifiers = options
.filter(opt =>
typeof opt.path === 'string' ? opt.path === k : opt.path.test(k)
)
.map(x => x.isVerified)
return verifiers.every(verify => verify(obj[k]))
})
return results.every(x => x)
}
type A = number
type B = string
const obj = { a: 1 as A, b: 'abc' as B }
verify(obj, [
{ path: 'a', isVerified: (x: A): boolean => x > 0 },
{ path: /b/, isVerified: (x: B): boolean => x.startsWith('a') }
])
For more details, please refer to the Playground link.
Unfortunately, I'm still encountering the following error:
Type '(x: number) => boolean' is not assignable to type '(t: T) => boolean'.
Types of parameters 'x' and 't' are incompatible.
Type 'T' is not assignable to type 'number'.