jaroslawpokropinski / eslint-plugin-strict-null-checks Goto Github PK
View Code? Open in Web Editor NEWEslint plugin that aims to reproduce strictNullCheck from tsconfig for easier migration
License: MIT License
Eslint plugin that aims to reproduce strictNullCheck from tsconfig for easier migration
License: MIT License
In multiple occasions the warning eslint (with rule strict-null-checks/all
) gives me returns "[object Object]" as the message, which is a little confusing.
Example:
const temp: () => Promise<string> = async () => {
const test: {
name: string | null;
} = {
name: null,
};
return test.name;
};
export default temp;
Running eslint over this file gives me:
temp.ts
1:7 warning [object Object] strict-null-checks/all
✖ 1 problem (0 errors, 1 warning)
function foo(v: unknown): unknown {
return v;
}
// This line gives a warning;
// Don't pass nullish arguments to a function that expects a non-nullish type.(strict-null-checks/all)
foo(undefined);
const fn1: (arg1: string | null) => void = (arg1: string | null): void => {};
fn1(null); // OK
type Action1<T> = (arg1: T) => void;
const fn2: Action1<string | null> = fn1;
fn2(null); // Error: Passing nullable argument to function that expects non nullable
E.g., it makes some troubles with using the React.useState
hook:
const [x, setX] = useState<string>();
setX(undefined); // Error: Passing nullable argument to function that expects non nullable
// The actual type of setX is:
// (value: React.SetStateAction<string | undefined>) => void
// that expands to:
// (value: string | undefined | ((prevState: string | undefined) => string | undefined)) => void
This rule ended up taking up 75% of my linting time, out of quite a few rules.
Since I run the linter every time I save, I unfortunately did have to disable this one.
Is this normal?
Not sure if it's an issue with this repo or with TS but here we go:
In my tests, I often have to declare a variable at the top, which I will use in the beforeAll
and the afterAll
.
Example:
describe('My test suite', () => {
let app: Server;
beforeAll(async () => {
app = await Server.init();
});
afterAll(async () => {
await app.close();
});
});
The problem is that I get a warning on the line let app: Server;
"Assigning nullable value to non-nullable variable".
Do you have a way around it?
I've also asked a question on SO: https://stackoverflow.com/questions/71490614/how-to-late-init-non-nullable-variables
Sometimes TS just can't figure stuff out and this type of statement is the only way 'round:
// Force the conversion
const smReq = req as unknown as ISmRequest<TParams, TRequest>;
Unfortunately this causes an infinite recursion in compareTypeObjects
here:
The workaround (for others encountering this) is to alter the function declaration in the above file to add an extra level
parameter...
function compareTypeObjects(left, right, checker, level) {
... and then increment it on each recursion and bail if the level hits a large number (I use 50) - notice that the call to compareTypeObjects
must be augmented with an increment to level
:
//...
if (level > 50) {
return true;
}
if (!compareTypeObjects(leftPropertyType, rightPropertyType, checker, (level||0)+1))
return false;
//...
this code should show an error in TestComponent where it tries to pass the nullable someProp on to the child component, where it is not nullable:
const ChildComponent = ({ someProp }: { someProp: SomeType }) => {
return <>{someProp.name}</>;
};
const TestComponent = ({ someProp }: { someProp: SomeType | null }) => {
return <ChildComponent someProp={someProp} />;
};
It should be noted that using a strictNullChecks in the global tsconfig does catch this issue, but since we're attempting to migrate incrementally, that won't be a good solution for us.
I have multiple projects in my repository with the following structure. I was trying to get this plugin working in both root level (for all of individual projects) or even for single project in src
folder. In both cases, without success. I'm receiving no warning messages even though I should.
my_project/
├── libs/
└── src/
├── app/
├── .eslintrc.json
├── tsconfig.json
├── tsconfig.app.json
└── tsconfig.strictNullChecks.json
.eslintrc.json
tsconfig.json
current configuration:
// my_project/src/.eslintrc.json
{
"extends": ["../.eslintrc.json"],
"overrides": [
{
"files": [ "*.ts" ],
"parserOptions": {
"project": [
"src/tsconfig.strictNullChecks.json"
]
},
"plugins": [ "strict-null-checks" ],
"rules": {
"strict-null-checks/all": "warn"
}
}
]
}
// my_project/src/tsconfig.strictNullChecks.json
{
"compilerOptions": {
"strictNullChecks": true
}
}
// my_project/src/tsconfig.json
{
"extends": "../tsconfig.json",
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
// my_project/src/tsconfig.app.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"strictNullChecks": false,
},
"files": [
"main.ts",
"polyfills.ts"
],
}
Any ideas how to get this plugin working? I can provide some minimalistic reproduction if needed. Thank you in advance!
Hi!
I came across an interesting scenario and was curious whether it was the plugin or typescript.
For the following function, arg1
shows an eslint error.
Looking at the message it says "Passing nullable argument to function that expects non nullable":
The type definition of Array locally shows that the argument is typed as any isArray(arg: any): arg is any[];
but it's still flagged as non-nullable.
Have you come across this before or do you have any hints where I can start looking? Thank you!!
Hej,
In this case, I assumed plugin should highlight that fn is potentially undefined but it does not.
type Fn = (() => void) | undefined;
const boo = (fn?: Fn) => {
fn();
};
boo();
type Foo = {
NullableString?: string
NonNullableString: string
NonNullableStringTwo: string
}
const bar = {
NullableProperty: undefined,
}
const data: Foo = {
NullableString: '',
NonNullableString: bar.NullableProperty?.bla, // even though we have optional chaining, undefined will still be set, the compiler/linter should know this
NonNullableStringTwo: bar.NullableProperty,
}
console.log(data)
In this example, tsc gives an error (as it should), but the eslint rule does not (since optional chaining would in theory give undefined, and set undefined on a non-nullable property)
Using version 0.1.1
Encountered the error Failed to load plugin 'strict-null-checks' declared in '.eslintrc.js': Cannot find module 'typescript'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.