- What language is this for? Typescript
- Which rule? S4144
- Why do you believe it’s a false-positive/false-negative? Because it directly contradicts documentation.
- Are you using
- SonarQube for IDE - which IDE/version? v5.9.1 for VSCode, not in connected mode
- How can we reproduce the problem? Scan the text below and note the warning on the line flagged by comments.
type ServerResponseCore = {
attr1: string;
attr2?: number;
};
type Routes = {
'alpha': ServerResponseCore & { alice?: number },
'beta': ServerResponseCore & { bob?: string },
'gamma': ServerResponseCore & { charlie?: number },
'delta': ServerResponseCore & { david?: string },
};
async function postJson<R extends keyof Routes> (
route: R,
routeBody: any, //pretend this is more careful
): Promise<Routes[R]> {
//pretend this is an HTTP request...
return {
attr1: 'demo',
attr2: 42,
};
}
const makeHTTPRequest = async <
S extends ServerResponseCore,
>(
post: () => Promise<S>,
handleRouteSpecificResponse: (response: S) => void,
) => {
const serverResponse = await post();
console.log(serverResponse.attr1, serverResponse.attr2);
handleRouteSpecificResponse(serverResponse);
};
const callAlpha = async (
alphaParam1: string,
alphaParam2: number, //...
) => {
const route = 'alpha' as const;
const routeBodyObj = {
//more complex construction in reality
alphaParam1,
alphaParam2,
};
const post = () => postJson(
route,
routeBodyObj,
);
type PostResponse = Awaited<ReturnType<typeof post>>;
const handleRouteSpecificResponse = (
serverResponse: PostResponse,
) => {
console.log(serverResponse.alice);
};
await makeHTTPRequest(
post,
handleRouteSpecificResponse,
);
};
const callBeta = async (
betaParam1: string,
betaParam2?: number, //...
) => {
const route = 'beta' as const;
const routeBodyObj = {
betaParam1,
betaParam2,
};
//Warning on next line:
//"Update this function so that its implementation is not identical
//to the one on line 45. [+1 location] (typescript:S4144)"
//Yet under "Issue Details" there are two listed "Exceptions":
//1. Functions with fewer than 3 lines are ignored.
//2. This rule does not apply to function expressions
//and arrow functions because they don’t have explicit names
//and are often used in a way where refactoring is not applicable.
//Thus per description, this rule should NOT flag a warning here.
//Also, this function gets typed differently than the one above.
const post = () => postJson(
route,
routeBodyObj,
);
type PostResponse = Awaited<ReturnType<typeof post>>;
const handleRouteSpecificResponse = (
serverResponse: PostResponse,
) => {
console.log(serverResponse.bob);
};
await makeHTTPRequest(
post,
handleRouteSpecificResponse,
);
};
See also this thread for a false positive on the typing point, but the documentation makes it seem like this rule shouldn’t be flagging here under the documented exceptions.