3.) Get started with Typescript
Some Basics
- TypeScript goes in .ts and .tsx files
- Adding a double backslash
//
at the beginning of a line will comment it out - Objects/variables have types, and functions will expect certain types. There is type checking. This is the major difference between TypeScript and Javascript.
- You can use
console.log(my_message)
to print a string stored in the variablemy_message
to the debugger console. - The
number
class is used to represent both integers and floats. Personally, I think this is an unfortunate choice, but then, I didn't invent TypeScript...
Declaring variables
Variables can be declared with let
, or const
. Variables declared with let
are mutable (they can be modified) and variables declared with const
are immutable (they cannot be modified).
const constantNumber:number=1;
let variableNumber:number=2;
variableNumber = variableNumber+1; // this is ok!
// constantNumber = 3; // this would cause an error
Formatted Strings
If you want to print a formatted string to the console, you can use syntax like:
const pi:number=3.1415927;
console.log(`The value of Pi is approximately ${pi}`);
Loops
for(let i=0;i<3;i++){
console.log(`The value of 'i' is ${i}`);
}
More on the Basics of TypeScript
There are a lot of great existing tutorials out there on TypeScript. A0 is pretty light when it comes what you need to implement, but that's because we expect you to spend some time setting up your development environment and familiarizing yourself with what, for most of you, we assume to be a new programming language. We have left plenty of comments in the starter code to help with this, but you will likely need to look to other online sources as well over the course of this semester. One good resource in particular is the TypeScript Playground which will let you test out small bits of TypeScript syntax as you develop an understanding of the language.
See Other Resources tab for links to additional TypeScript learning material
Some More Advanced TypeScript Concepts that Show up in A0
Spreader Syntax
In src/Assignment1/math/Mat2.ts
, you may see a ...
syntax serving for different purposes.
This syntax behaves like writing out the contents of a list separated by commas. For example, if we have an array let a=[1,2,3,4]
and we put it in another array let b=[a]
, the result would be an array inside of an array [[1,2,3,4]]
. However, if we use the rest operator let c=[...a]
it is as if we listed out the elements of a
when assigning c
, so c
will have the value [1,2,3,4]
just like a
.
Example: spread content of an array into another array
const a = [1,2,3];
const b = [4,5,6, ...a];
console.log(b);
output:
[ 4, 5, 6, 1, 2, 3 ]
Rest Syntax
We can also use the elipses when defining function arguments to indicate that we want to accept an arbitrary set of inputs.
Example: Rest Syntax for an unknown number of arguments
function f(a:type1, b:type2, ...args:any[]) {
console.log(args);
}
f(1, 2, 3, 4, 5);
Output:
[ 3, 4, 5 ]
Pay attension that this feature is used in the function overload tutorial below.
These are all you need to know about the spreader syntax for now. There are more usage of the spreader syntax, like spread array content as function arguments, deconstruct an array or object, and so on. To learn more, you can check out Spread syntax (...) - JavaScript | MDN.
Function Overloading (really, function call signature overloading)
Typescript is a bit odd in that you are allowed to overload the way functions are called, but not how they are implemented. Why? This restriction turns function overloading into just another kind of type checking, and that's just what TypeScript does best. Think of it as just another kind of type checking. It can tell you whether the arguments you provided are valid, but it's not going to change whatever function you wrote to deal with those arguments. So you can tell TypeScript that different sets of arguments are ok, but the actual function you write needs to be able to deal with any of these "ok" arguments.
In src/Assignment1/math/Mat2.ts
, we have overloaded the call signature for the constructor
and times
functions of our Mat2
class. This makes creating matrices more convenient and makes multiplication behave a more like it's abstract mathematical counterpart.
For example, You can construst a Mat2
object with different signature, like
let m1 = new Mat2();
let m2 = new Mat2([1,2,3,4]);
let m3 = new Mat2(1,2,3,4);
And overloading Mat2.times
(matrix multiplication) lets us apply it to other matrices, vectors, or scalars, just as we would with matrices in more casual writing (nothing says 'casual' like matrix multiplication...):
// prepare matrices and vector to use
let m = new Mat2(1,2,3,4);
let m1 = new Mat2(5,6,7,8);
let v1 = new Vec2(2, 3);
// demo of different times usage
let a = m.times(m);
let b = m.times(v);
For more details on overloading in Mat2
, see the code comments.
Testing for equality
"Whoa, a double equals ==
"
Double equals sign tests whether two values or equal after attempting to cast them to the same type.
"Now it's starting to look like a triple equals ===
"
Tripple equals sign tests whether two objects have equal values and types.