Open binggg opened 6 years ago
how do we work around this?
got it, it's because typescript 2.7.2 included a strict class checking where all properties should be declared in constructor. So to work around that, just add a bang sign (!
) like: name!:string;
Try adding "strictPropertyInitialization": false
to your compiler options.
No, not gonna do that, typescript enforces strictness, I'd much rather see !
s than dumb down TypeScript :smile:
For those using an older typescript version or IDE (one which doesn't recognize the "!
" feature) here is an alternative to turning off strictPropertyInitialization
:
Use a public get()
to enforce strong-typing and give a meaningful error message in the (presumably unlikely) case the object is used before being initialized:
private _logger: MyLogger | null = null;
public get logger(): MyLogger {
const self: MyClass = this;
if (!self._logger) {
throw new Error("MyLogger in MyClass is not initialized yet.");
}
return self._logger as MyLogger;
}
Then, in the MyClass constructor you set _logger
, and elsewhere you use logger
.
Of course, if MyLogger has no construction dependencies you can just create it right in the get()
instead of throwing the error -- e.g., do lazy initialization. But when that's not convenient, this gives some protection while eliminating compiler errors/warnings.
typescript should be more flexible instead of being another C++/Java.
@calidion , in other words JavaScript you mean? You can turn off quite a lot of features and dumb TypeScript down to a extend and it'll start deffering to any
where you don't declare a type, but then it looses the point. TypeScript being strict is what we want, and because of that, it's easy to refactor and write more obvious code :slightly_smiling_face:
@cyberhck
and write more complex code too.
code should keep clean and simple.
i use typescript because it hides differences between versions of node.js/ecma.
not because it wastes time and provide type info.
type info may be good for large projects. but it is not that important for small projects. and some grammatical errors are just time wasting and should only be warned or auto corrected.
I agree on writing clean and simple code. Sure. But if you say type info isn't necessary for small projects, then maybe just don't use TypeScript and go for plain JS, (or disable most of feature in TypeScript), that will just work fine. TS does give you ability to enforce less strictness. But here's something, if it's a small project you're doing for yourself, and you know exactly what's gonna happen, like "coming soon" page for your new website, or similar, then yes, sure, typescript with minimal strictness or even JS will do.
But what I've seen is projects starting minimal, and client asking for some change which touches quite a bit of code, even though it's a small project, I'd still prefer type safety.
But if it's really a coming soon page kinda, I think normal JS will do just fine (or a event page which won't be used after a week or so)
type safe means not direct data conversion or type casting which leads to time and code wasting on type conversion. code is much complex with the result of the introduction of generic programming.
scripting languages are introduced not to use generic programming due to their dynamic nature.
as far as i can see, typescript may not be on the right track by bring new burdens to the scripting language, javascript, developers.
For larger projects, I wouldn't be comfortable with TypeScript being more flexible and allowing developers to do more stuff, (for example property initializers may not be very useful in this project, but it's quite useful feature on a lot of other places), so if you find TypeScript more restricting, just turn some options off. There's no harm in that. But for larger project, I wouldn't be comfortable with that.
Imho, the most important point of strong typing is that it throws errors to the programmer, not to the user. If you remove all checking from typescript, why use it? I like this hilarious talk about the lack of type safety in javascript.
typescript provides translation to different js versions. that is why i use it. not because it provides type checking which is much useless and time wasting.
if you like type checking, you should use c++ OR java at first place which is faster and more efficient.
why you use javascript as your working environment then?
unless you're talking about webassembly, you can't use C+++ or Java on the web. For converting to different JS version, you can still use babel, not sure why TypeScript is required for you. Anyone can transpile to ES6/ES5 using babel, it's not just TypeScript.
We use TS/JS because there's no alternative for the web, you could argue about webassembly using C, but that's not production ready. For anything other than web, I'd NOT use anything which compiles down to JS at all. I'd go for other languages.
If you're using TS just to transpile to different version of JS, maybe you should look into babel :)
to me it is mostly another babel which can keep code much more consistent.
with which i don't need to think if the features are supported by certain js version, and don't need to change the code when time goes on.
Sometimes i do use types to limit input when necessary, but I won't use strict typing extensively. it is a bonus not a must. especially I would forbid using generic programming when it is a script language which is created to avoid generic programming.
Again, like I already mentioned, you CAN remove all types and make typescript as simple as JS, but for people who have to deal with projects which explodes very quickly, we need typescript to be as strict as any other strongly typed language.
If you're using mostly like another babel, you're using the tool which can technically do what you want it to, but it's about so much more than that.
So you can configure the way you like, it's your opinion, and a lot of people hold that opinion, trust me, I've seen these comments :) but I'm not one of them.
For you it's a bonus, for me, it's a must when I'm working.
I like the help I get from TypeScript. I don't have any checks like: if something is a number or not, I just declare it, and typescript does the rest for me.
I am not forcing everyone to be on my side, but still there are people who want to force their idea to others.
I do appreciate the features typescripts bring to us, but I do resist the idea using types extensively within a scripting language as well.
types can be helpful and types can be harmful. It is an art on how to balancing them, so i choose to use types when necessary while keeping code simple, clean, understandable.
There is no truth in that strong types are superior than weak types. if it is true, then scripting languages would never come into being.
So the idea using strict typing is good for large projects is nonsense.
the largest package repositories are pip, npm, gem which are backed by languages with weak types, none of them are strong typed languages such as java, c++.
so type checking is irrelevant to how large your project is. why should there always be someone trying to convince someone else that strong types are superior?
I'm trying to force my opinion to you, I never did that, your comment was: "typescript should be more flexible instead of being another C++/Java.", and I said you CAN configure typescript to not be strict, it's upto you.
About having largest repositories in weakly typed language, first I'd like to say this:
Second, just because it has a large number of package doesn't say anything, if we count number of users, then wordpress serves most of the website in the world, does that mean wordpress has a greater codebase? No! It just happened to happen. And, BTW, npm is big doesn't mean they have big projects, there are projects where you wouldn't need type checking, eg: left pad. Why would you want to typecheck that, but if you wanted to, you could.
Third: if typechecking is irrelevant to how large your project is, why would facebook move from PHP to hack (performance AND typechecking), why would facebook introduce flow?
Just because it's popular doesn't mean anything.
Finally: Again, I'm not saying my view is superior to yours, you have your view and I have mine, you're making a statement: "typescript should be more flexible instead of being another C++/Java." which degrades my view, it's not like typescript is stopping you from doing stuff in your way. It's flexible.
What you're saying is it should remove everything and make it a plain js transpiler, if you wanted that, go with a transpiler, not a type checker.
You CAN configure your project to not have strict typings, that's how you like it. I WANT to be able to configure my project so a jimmy won't fuck up in production, that's how I like it.
If you still think adding types is ugly, let's consider the following:
class Calc {
static add(a: number, b: number): number {
return a + b;
}
static sub(a: number, b: number): number {
return a - b;
}
static mul(a: number, b: number): number {
return a * b;
}
static div(a: number, b: number): number {
return a / b;
}
}
Let's rewrite the same in JS but we need changes: first, we want to document parameter types anyway, and we want to ensure parameter type is actually correct, else there's silent logic error. And docs would be in each method, to save space, I'm doing only in one.
class Cal {
/**
* Add
* @param {number} a
* @param {number} b
*/
static add(a, b) {
Cal.ensureNumber(a, b);
return a + b;
}
static sub(a, b) {
Cal.ensureNumber(a, b);
return a - b;
}
static mul(a, b) {
Cal.ensureNumber(a, b);
return a * b;
}
static div(a, b) {
Cal.ensureNumber(a, b);
return a / b;
}
static ensureNumber(a, b) {
if (typeof a !== "number" || typeof b !== "number") {
throw new Error("both arguments must be number")
}
}
}
Now when I run these:
Calc::add(1, "something");
and
Cal::add(1, "something")
Before I deploy anything or even use in browser, I already know, actually if you have good IDE, you know while you're typing if you went with type check option.
If you were to use JS, you'd build and it'd work and get error which potentially might be seen by users.
For me it looks like using TypeScript requires lesser keystrokes (unless you kick out docs and error checking in JS, if that's the case, you might as well burn your codebase)
AGAIN FOR LAST TIME: I'm not saying you should use types, but don't criticise the people who want to. I think first class is more clean, beautiful, easy to maintain than the later one.
your are making a bad example on how to use scripting language properly.
when using scripting language, you need not to make sure your type is correct.
so the code should be:
class Calc {
static add(a, b) {
return a + b;
}
static sub(a, b) {
return a - b;
}
static mul(a, b) {
return a * b;
}
static div(a, b) {
return a / b;
}
}
and a
, b
needn't to be a number when other types are applicable.
where calc::add('aa', 'bb') is ok. when it produce expected result.
why should i check type every time? what i needed is it solve my problem and improve my code efficiency.
And you are absolutely wrong on I think first class is more clean, beautiful, easy to maintain than the later one.
I think most users are just using it as javascript replacement where javascript syntax is changing.
we just want our code to be steady. not because we like strong types. although type checking sometimes do help.
And I should say, if you think strong types really good? why not just use C++/Java/C#? web assembly is coming, you've good the opportunity.
https://www.youtube.com/watch?v=M3BM9TB-8yA&t=2s https://github.com/ry/deno context: guy who created nodejs thinks nodejs is a bad idea because of typesafety, and he's now working on deno which runs typescript.
If you think I'm wrong on that, mention why you think I'm wrong. I think you're absolutely wrong and I'm correct because of the following premises:
When I see your class, I expect it to work just by doing Cal::(1, myValue)
, but it doesn't because myValue is not defined and it throws a run time error.
And if you're trying to use javascript on production without validating inputs first, good luck with that.
Scripting language have their own place (while scripting), not while building complex application which we rely on.
Most users aren't using just as replacement, that's what you think, which doesn't make it true.
I'd much rather use C++/Java/Any thing really, but if you didn't know, webassembly is coming, it's not reliable yet, unlike a lot of people I've to ship to customers whose browser isn't new.
calc::add('aa', 'bb')
is okay in your case, but let's see something shall we?
consider a dom where I've got 2 input boxes, and I've to display a sum of those on a div when anything changes.
here's a sample link
here's js I used, and notice html input type is number.
const firstInput = document.getElementById("first");
const secondInput = document.getElementById("second");
const resultContainer = document.getElementById("result");
const performAdd = () => {
const firstValue = firstInput.value;
const secondValue = secondInput.value;
resultContainer.innerHTML = firstValue + secondValue;
}
const listenChange = (element) => {
element.addEventListener("keyup", performAdd);
}
listenChange(firstInput);
listenChange(secondInput);
When I try to add 1 and 2, it says 12, that's definitely not fine in my case. I don't want it happening, if I wanted it happening, I'd much rather convert first. Just because it's good when we do with simple strings doesn't mean it's good everywhere.
Say you did similar, you didn't check parameters, you created a library which others use, do you think they're going to be happy when there's silent errors? At least report an error, and you don't have documentation, come on! In my case, my class self documents.
Now you might say, if I don't parse it, I'm incompetent and shouldn't be doing programming at all, but the point is, it's something you've to remember, but typescript would catch it. This is one of the example, there might be some more.
Scripting languages are good for fast iteration, but again IMO, they're not very useful for larger codebase.
Again for the last time, let me be clear, I don't care if you think JS can be used to build any complex systems, even the banking ones, I don't care if you do so, I wouldn't trust myself with that, but I don't care if you do anyway.
I don't care if you dumb down typescript to make it more like JS than TS, BUT just because I like having strictness doesn't mean you've to criticise about that. If you don't want strictness, it's simple, TURN THE DAMN THING OFF and don't complain.
But let others who like it enjoy, you're acting like a guy who doesn't like clubs and says clubs should be like quite hotel rooms. Let people enjoy what they want.
regret on node having nothing to do with weak types or strong types. I won't waste time on this.
Woah... I ended up in "that" part of Github again 😆
Try adding
"strictPropertyInitialization": false
to your compiler options.
thank you!
If you are not initializing a property right away (during the construction phase), you should explicitly indicate that it could be undefined: private name: string | undefined;
or private name?: string;
, then the warning would go away. It makes a lot of sense, actually, because everyone working with the code will see that it could be undefined, including the compiler.
I would not recommend to use the strictPropertyInitialization: false
option, because it will make static analysis weaker.
I never thought of it, if I had done that instead of using bang (!
), I'd not have that bug yesterday, just yesterday, wow.
I'm gonna create a lint which will not allow me to use bang and set can be undefined instead. So we always check.
Thanks @slavafomin
typescript version 2.7.2