Reputation: 100
I want to create a function that loops over key/value pairs in an object and that returns an object with the same keys, but each value has now become a function. I want to make sure that typescript correctly grasps the returned object for autocomplete. This works in de following silly function:
interface Args {
[layer: string]: Boolean
}
function sillyFunction<T extends Args>(layers: T): T {
return layers
}
sillyFunction({ layerName: true }).layerName // this works
But now I have the following code, where the layers object (key/boolean pairs) is used to create a new returnObject with key/function pairs.:
interface Args {
[layer: string]: Boolean
}
interface ReturnedObject {
[layer: string]: Function
}
function createFunctions<T extends Args>(layers: T): T {
let returnObj = {} as ReturnedObject;
for (let layer in layers) {
returnObj[layer] = (label) => `${layer} ${label}`
}
return returnObj;
}
createFunctions({ layerName: true }).layerName // doesnt work
This obviously gives me the error 'ReturnedObject' is not assignable to type T. How can I make sure that typescript 'understands' that the keys inside the object are still the same, but values have become functions?
Upvotes: 1
Views: 2257
Reputation: 250406
You need to use a mapped type to transform T
to a new type with a the same properties, but a different type for each property. The predefined type Record
will work well in this case, since all the keys will have the same type. Also I would be more specific then Function
about the type of the function, Function
is the any
of function signatures, it allows invocation with any parameter
interface Args {
[layer: string]: boolean
}
type ReturnedObject<T> = Record<keyof T, (label: string) => string>
function createFunctions<T extends Args>(layers: T): ReturnedObject<T> {
let returnObj = {} as ReturnedObject<T>;
for (let layer in layers) {
returnObj[layer] = (label) => `${layer} ${label}`
}
return returnObj;
}
var l = createFunctions({ layerName: true })
l.layerName("")
Upvotes: 3
Reputation: 2878
your "createFunctions" return type is T but you expected to be ReturnedObject.
just define return type as ReturnedObject
function createFunctions<T extends Args>(layers: T): ReturnedObject
and it should work
Upvotes: -1