Type & Interface Members
Usage
Reporting unused type and interface members is disabled by default. To enable
this, make sure to include the typeMembers
issue type:
knip --include typeMembers
Below are code examples to get an idea of what Knip should catch. Also see the fixture folders (1 & 2) for slightly more involved examples.
Use JSDoc tags to exclude individual members and ignoreMembers in the Knip configuration file to exclude matching members from the report.
Add --fix
if the results are good enough to auto-remove the unused type
members.
Interface Members
In the next example, Dog.wings
is reported as unused:
export interface Dog { legs: number; wings?: boolean;}
const charlie: Dog = { legs: 4,};
Non-optional instance members are reported, but should also be caught by the compiler.
Type Members
In the next example, Pet.fins
and Cat.horn
are reported as unused:
export type Pet = { legs: number; fins: boolean;};
export type Cat = { legs: Pet['legs']; horn?: boolean;};
const coco: Cat = { legs: 4,};
Function Arguments
In the next example, Args.caseB
is reported as unused:
export interface Args { caseA: boolean; caseB?: boolean;}
function fn(options: Args) { if (options.caseA) return 1;}
fn({ caseA: true });
Function Arguments
In the next example deep.unusedProp
is reported as unused:
export type ComponentProps = { usedProp: boolean; deep: { usedProp: boolean; unusedProp: boolean; };};
const Component: React.FC<ComponentProps> = props => ( <span> {props.usedProp} | {props.deep.usedProp} </span>);
const App = () => <Component />;
JSX Attributes
In the next example unusedProp
is reported as unused:
export interface ComponentProps { usedProp: boolean; unusedProp: boolean;}
const Component: React.FC<ComponentProps> = props => null;
const App = () => ( <> <Component usedProp={true} /> <Component {...{ usedProp: true }} /> {React.createElement(Component, { usedProp: true })} </>);
Rationale
One of Knip’s main goals is to find unused exports, not unused members. It’s built around a module and dependency graph to link up imports and exports.
Finding and fixing enum and class members is already supported, but these features are limited to those on exported enums and classes. From the perspective of “find unused members” alone this is perhaps an odd limitation. So why even support this? It’s just that Knip happens to be in a great position to extend its reach from exports to also find and fix unused members on those exports. There’s value in a tool that finds and fixes unused members of classes, enums, types and interfaces in an automated fashion. The question is: does the value outweigh the cost of the scope creep? In any case, it’s exciting to explore this area.
ignoreExportsUsedInFile
Only members of exported interfaces and types are considered. Don’t start exporting or reusing interfaces and types for the sake of Knip detecting unused members.
Having said that, ignoreExportsUsedInFile can be enabled for exported types and interfaces that aren’t imported anywhere, and then unused members can be “un-ignored” (i.e. reported) like so:
{ "include": ["typeMembers"], "ignoreExportsUsedInFile": { "type": true, "interface": true, "member": false }}
ISC License © 2024 Lars Kappert