TS7017 implict any type + type inference

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

TS7017 implict any type + type inference



Here's the condensed snippet that's erroring:


export default function formatSql(this: EscapeFunctions, sqlQuery: string, values: QueryParams)

if (isPlainObject(values))
console.log(values[p]); // <-- Element implicitly has an 'any' type because type 'QueryParams' has no index signature.
else if (Array.isArray(values))
// ...
else
throw new Error(`Unsupported values type`);

// ...



QueryParams is defined as:


QueryParams


export type QueryParams = StringMap | any;
export interface StringMap
[_:string]: any,



So, StringMap has an "index signature" if I'm not mistaken, and isPlainObject is defined as:


StringMap


isPlainObject


export function isPlainObject(obj: any): obj is object
return isObject(obj) && (
obj.constructor === Object // obj =



So I'd think that the isPlainObject check would rule out the any type, and thus values should necessarily be inferred as StringMap, but that doesn't appear to be what's happening.


isPlainObject


any


values


StringMap



Even if I make isPlainObject return obj is StringMap, Typescript still complains.


isPlainObject


obj is StringMap



How come? Is there any way I can make this work without typecasting everything?




1 Answer
1



Technically, an Array still conforms to the type [key: string]: any. You can verify this by doing const test: StringMap = ;. The TypeScript compiler will not complain. So you first have to rule out the possibility that values is an array.


[key: string]: any


const test: StringMap = ;


values



Next, your function isPlainObject has the return type defined as obj is object. That is too generic, and will cause your code block to "forget" that the object has an index signature. It needs to be obj is StringMap.


isPlainObject


obj is object


obj is StringMap



So in practice, you need to do two things:


if


isPlainObject


obj is StringMap



Basically it will look something like this:


export function isPlainObject(obj: any): obj is StringMap
// ...


export default function formatSql(values: QueryParams)
if (Array.isArray(values))
// ...
else if (isPlainObject(values))
console.log(values[p]);
else
throw new Error(`Unsupported values type`);






I have to check for array first because arrays are technically objects? Is that why?
– mpen
11 hours ago






I just edited the solution to add more explanation.
– Stefano Dalpiaz
11 hours ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

Executable numpy error

PySpark count values by condition

Mass disable jenkins jobs