Description
Detecting Uncalled Function Statements
- Started as an editor-motivated issue.
- In conditions we can detect these cases, but not plain statements.
- Lots of good stuff, but false positives.
- Especially for dts-lint.
- Can view this as something like
noImplicitReturns
- another lint-like rule.- Feels like we need better principles on these.
- Original bug isn't caught by this check!
- What about fluent-like libraries?
expect(name).not.toBeFalsy
- Yeah, these seem legitimate.
- Over-eager errors?
foo.bar
- "oh, there's an error, doesbar
no exist? oh, no, it's just an unused expression"- Feels like that's a bad UX.
- Can this be a lint rule?
- Yes - and in fact, it doesn't need to be a typed lint rule either.
- We were more motivated by the callback example.
Variance and Variance Annotations on Type Parameters
-
We have issues with circularities when trying to measure variance of type parameters.
-
What if we had a way to tell the type system "if you need the variance when you hit a circularity, here it is"
type Foo</** @in @out */ T> = { // ... };
-
Could also have some logic to say "ignore the circular references, but makes our results imprecise in the face of circularities (and makes them order-dependent).
-
Some don't like the reasons of variance assertions - nice escape hatch for some performance issues though.
- Maybe some way of being able to record the measurements of
T
inFoo<T>
that don't occur in the circular (in)direct references toFoo<T>
by deferring those measurements. So when you're going into a loop, defer those measurements so that you have more information for later. - Need to find a way to record these locally, but not globally for other operations.
- Maybe some way of being able to record the measurements of
-
Two things really - algorithmic changes, and variance annotations. Mostly want to discuss annotations right now.
-
Do we want to have a flag that tells users when variance is possibly measured incorrectly?
- Is it a diagnostics flag? Is it a strictness flag?
- Would flag a LOT of types.
- Is it a diagnostics flag? Is it a strictness flag?
-
Right now have a prototype.
- JSDoc.
- Have an
@in
and@out
and can combine with@in @out
to specify invariant. - No checking whether they're the case.
-
Why "in and out"? Python uses explicit "contravariant"?
out
means "I only use this in output/read positions"in
means "I only use this is input/write positions
-
How does this work with structurally similar types? For example, take a contravariant
Box<T>
:type Box<in T> = { value: T; }
-
What can you initialize this with?
type Box<in T> = { value: T; }; // Error... let y: Box<string | number> = { value: 42; } as Box<number>; // Okay??? let x: Box<string | number> = { value: 42; };
-
Can't lie to make a write-only
Box
, otherwise things go off the rails.
-