'no-inferrable-types' and 'typedef' rules conflict #711
Comments
Good catch, thanks for the heads-up. I added the Longer term, I think we'll either want to integrate |
I am facing the same issue. |
Yes same here, I would like to have ability to have both the rules co-exist. |
+1 |
let id: number = 0;
for (let job: string of NAMES_PROFFESSIONS) {
/** some code */
id++;
} (no-inferrable-types) LHS type (number) inferred by RHS expression, remove type annotation |
+1 |
Does your definition of "inferrable" types include constructor assignments? // BAD (this hurts my eyes to read)
let labels: Map<string, string> = new Map<string, string>();
// GOOD (type is obvious)
let labels = new Map<string, string>(); but also... // BAD (in a diff, it's not obvious what this type is)
let labels = this.buildLabels();
// GOOD
let labels: Map<string, string> = this.buildLabels(); |
Yes, it's dangerous. If I want to simplify my code and prevent to use type declaration for directly initialized variables, I can't do this strictly and this brings to such thing: let x = 2;
let y;
let z: number;
x = 1;
y = 1;
z = 1;
x = 's'; // Type 'string' is not assignable to type 'number'
y = 's'; // It's OK
z = 's'; // Type 'string' is not assignable to type 'number' It's may be a very useful option to allow skip type declaration only for initialized variables. |
… and really not only for primitive types, as @pgonzal says! const onChange: () => void = () => this.update(); |
👍 Ideally (imo) I would like a way to say "always require a typedef, unless the type is inferrable". Which I don't think is possible right now. |
I ran into this and made an See PR: #1190 if you want to try it out |
It's been a while since the original issue was submitted. Is the recommend option at this point to disable |
Would accept a PR to:
The There's also the tricky case where some things that are initialized need a typedef anyways, as in the following snippet: interface Literal {
field: "value"
}
const literal0 = {
field: "value",
};
const literal1: Literal = {
field: "value",
};
const func = (obj: Literal) => { };
func(literal0); // Error! Type 'string' is not assignable to type '"value"'.
func(literal1); |
Also, while we get this fixed, wanted to mention that there are likely some great 3rd-party rules out there, like |
@jkillian thanks for the recommendation, I think that's actually what I wanted. There is a very good post about avoiding About: interface Literal {
field: "value"
}
const literal0 = {
field: "value",
};
const literal1: Literal = {
field: "value",
};
const func = (obj: Literal) => { };
func(literal0); // Error! Type 'string' is not assignable to type '"value"'.
func(literal1); I don't see how this could be an undesired behavior nor a tricky case. You want to make sure that I know is not a good use case, but most of the cases when you are using a literal, you probably want that literal, not a primitive. |
I have the following configuration: "no-inferrable-types": true,
"typedef": [true, "call-signature", "parameter"], And this code: private static readonly DEVICE_UID: string = 'device_uid';
private static readonly DEVICE_PLATFORM: string = 'browser';
private static readonly AGENT_DEFAULT_ICON = 'http://localhost:3000/icon.png'; Why I'm not getting error in the two first declarations? |
@sandrocsimas Interesting, but off-topic I think; AFAICT that problem's unrelated to this issue. I'd suggest you start another issue (fwiw!). |
@estaub , yes I will. I'm getting the same behavior even without the typedef rule. |
@sandrocsimas that's because it's a readonly property, and such Typescript infer its type as a literal. Typing it as a string you are telling that it should have a string, it does not necessarily will have that literal value and the value should not change statically. |
After discussing the conflicting 'typedef' vs. 'no-inferrable-types' TSLint rules (palantir/tslint#711) in the Discord #development channel, the conclusion was to disable this rule in order to be uniform and explicit in what all declarations are. Although it's more verbose, it will help us out in the long run.
It would be nice to have a 'require-typedef-except-inferrable' rule. |
@FiretronP75 as @jkillian said, that's just |
@michaeljota thanks, I didn't realize the |
I see why this would be something wanted, but having |
Has this been fixed in the latest version? |
I still don't think this is on the roadmap. You should consider using |
☠️ TSLint's time has come! ☠️ TSLint is no longer accepting most feature requests per #4534. See typescript-eslint.io for the new, shiny way to lint your TypeScript code with ESLint. ✨ It was a pleasure open sourcing with you all! |
🤖 Beep boop! 👉 TSLint is deprecated 👈 (#4534) and you should switch to typescript-eslint! 🤖 🔒 This issue is being locked to prevent further unnecessary discussions. Thank you! 👋 |
Hi again,
I am not sure if this is issue or design decision, but I can see conflict between rules
no-inferrebale-types
andtypedef
.Ex.
Snippet from https://github.com/palantir/tslint/blob/master/docs/sample.tslint.json:
When I have these two rules turned on, I get:
Adding type annotation
number
to variablei
causes in turn following error:Is there any way to have these two rules coexisted with each other?
For example, I want to have inferrable variables directly declared with primitive type (as rule doc says:
number
,boolean
orstring
), but on the other hand, I want to force typedefs on non-primitive types.Thanks,
O.
The text was updated successfully, but these errors were encountered: