Issue
Let's say I have a couple of functions (they're GraphQL resolvers but I don't think it's that relevant):
function doSomething: (args: doSomethingInput) => {
const { id, accessToken, type } = args.input
// more code here that uses those variables...
}
function doSomethingElse: (args: doSomethingElseInput) => {
const { id, accessToken, points } = args.input
// more code here that uses those variables...
}
type doSomethingInput = {
input: { id: string, accessToken: string, type: string }
}
type doSomethingElseInput = {
input: { id: string, accessToken: string, points: string }
}
I would like to sanitize the input that's passed to those function, so my idea is to do something like this using the validator library:
import validator from 'validator'
function doSomething: (args: doSomethingInput) => {
for (const [key, value] of Object.entries(args.input)) {
const keyTyped = key as keyof typeof args.input
args.input[keyTyped] = validator.escape(value)
}
const { id, accessToken, type } = args.input
// more code here that uses those variables...
}
This would allow, for example, that an accessToken
that was passed as such 28502307<script>alert('HELLO')</script>
to my function will then look like this 28502307<script>alert('HELLO')</script>
which I prefer.
However, I would like to apply this to the input of all my resolvers. That's why I would like to write a function to externalize that behavior:
import validator from 'validator'
function sanitize(inputParameters: object): object {
for (const [key, value] of Object.entries(inputParameters)) {
inputParameters[key] = validator.escape(value as string)
}
return inputParameters
}
However it gives me this error:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
No index signature with a parameter of type 'string' was found on type '{}'.
And this doesn't work either:
import validator from 'validator'
function sanitize(inputParameters: object): object {
for (const [key, value] of Object.entries(inputParameters)) {
const keyTyped = key as keyof typeof inputParameters
inputParameters[keyTyped] = validator.escape(value as string)
}
return inputParameters
}
this time with this error:
Type 'string' is not assignable to type 'never'.
(I found that typecast line somewhere else in here in stackoverflow)
So, how can apply a generic function to objects with different types?
Solution
I don't know what your inputParameters
will contain, but you cannot access arbitrary keys of object
type (see this answer). So instead I recommend you use the Record
type with any
as key (allowing any string or number key) and unknown
value type (allows for any value, but continues to check the type).
If you don't know inputParameters
value types ahead of time, you might want to check them first, since using as
assertion (value as string
) just disabled most of typescript checks and can lead to undesired consequences. Instead you can check if value
is a string
with typeof value === 'string'
and if it's not, ignore the value (or go deeper if the value itself is a Record
).
Here's the sanitize
function with Record
type:
function sanitize(inputParameters: Record<any, unknown>): Record<any, unknown> {
for (const [key, value] of Object.entries(inputParameters)) {
inputParameters[key] = validator.escape(value as string)
}
return inputParameters
}
More on Record
in the typescript docs,
Answered By - Murolem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.