Skip to content

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:

Terminal window
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