TypeScript Flashcards
In dynamically typed languages, a variable’s type is determined when?
At runtime, based on the type of value it is assigned.
In statically typed languages, each variable must be assigned a specific data type when it is declared, and functions must specify the type of value they return.
In TypeScript, compile-time errors occur during…
the process of converting the TypeScript code into JavaScript code.
runtime errors occur in JavaScript when…
the code is being executed
The TypeScript compiler can detect both ____ and ____ before the code is executed.
syntax and type errors
What is type safety?
Type safety ensures that values in your code are used in a manner consistent with their declared types, helping catch potential errors at compile time rather than at runtime.
Changing existing JavaScript programs to TypeScript programs won’t “break” them, they will still compile and run. However, the TypeScript compiler will now throw a variety of helpful warnings and errors at build time, which we can resolve by updating our code and adding type annotations.
What are type annotations?
Type annotations are used to explicitly specify the type of the variable:
let myName: string = "Alice";
What will be logged to the console and why? How can we prevent this behavior?let numbers: Array<number> = [1, 2, 3, 4, 5];
let myNum: number = numbers[5];
console.log(myNum);
In the above code, we are able to assign the value undefined to the variable myNum, even though myNum has the type number. This seems like a bug, but TypeScript doesn’t raise a warning.
The issue is that TypeScript can’t know how long the array is, or will be. In other words, because JavaScript arrays have a dynamic length, the TypeScript compiler doesn’t know whether any particular index is out of bounds. As a result, it infers that any elements returned from the array are of the type the array contains.
You can add code to check if the variable is undefined
. Or you can use the noUncheckedIndexedAccess
compiler option in TypeScript.
What is the noUncheckedIndexedAccess
compiler option?
The noUncheckedInexedAccess
option is used to improve type safety by ensuring that all indexed access to object properties is properly checked. When this option is enabled, TypeScript treats every object property access using an index as potentially undefined, unless the type system can definitively determine that the property exists.
Tuples can be very useful in TypeScript when you want to…
work with a collection of values that have a specific order and data type.
let aTuple: [string, number, boolean] = ["Launch School", 1, true];
Primary differences between arrays and tuples?
Tuples have a fixed length.
You cannot access an out-of-bounds index of a tuple.
What happens if you call .push()
or .pop()
on a tuple? Why?
As long as you are pushing a valid type for the tuple, the TypeScript compiler will not raise an error. The problem is that tuples are just arrays, and thus they have all of the methods that arrays have. For this reason, it is generally considered a best practice to avoid using methods like push() and pop() when working with tuples as this can lead to unexpected behaviors.
This array consists of both string and boolean values. If you had to assign a type definition to myArray, what would it be?
const myArray = ["is", "launch school", "awesome", true, "or", false];
const myArray: (string | boolean)[] = [
"is",
"launch school",
"awesome",
true,
"or",
false,
];
____ is used as the return type for functions that don’t return a value.
void
What is type inference?
Type inference is a feature in TypeScript that allows the compiler to automatically deduce the types of variables when they are not explicitly specified.
What is meant by a method/function signature?
In TypeScript, a method signature (or function signature) defines:
1) the name of a method
2) the number and types of its parameters
3) the type of its return value.
It specifies how a method can be called, what arguments it takes, and what it returns, without providing the method’s implementation.
void
represents…
the absence of a value
Values with the void type cannot be…
1) assigned to any other data typeconst result: void = greet("Jane");
const myUndefined: undefined = result; // Type 'void' is not assignable to type 'undefined'
2) cannot be used in a conditional to test truthiness.const myBool: boolean = result ? true : false; // An expression of type 'void' cannot be tested for truthiness.
Why does TypeScript raise an error with the following code?
function logSum(a: number, b: number): void {
const sum = a + b;
console.log("The sum of", a, "and", b, "is", sum);
return sum;
}
logSum(3, 4);
Because a function with a return type of void
is intended to not return a value and sum
is returned. If a function’s return type is void
and it has an explicit return it should only return undefined
, otherwise TypeScript will raise an error.
What is a literal type? List some specific examples.
In TypeScript literal types are used to describe the literal values that a variable can have.
Specific examples are string literals, numeric literals, and boolean literals.
let five: 5 = 5;
let hasName: true = true;
What is any
?
any
is a special TypeScript type that represents any possible value.
In TypeScript, type errors happen at…
compile-time
What is the following an example of?
type Person = { name: string; age: number };
The code snippet is an example of type aliasing.
What is type aliasing?
Type aliasing is when we define new custom types based on existing type using the type
keyword.
What is meant by an object’s shape?
The “shape” of an object refers to the structure of its properties and their types. When we talk about the shape of an object, we are referring to the names and types of the object’s properties.
In TypeScript’s structural typing rules, if we have two types, TypeA
and TypeB
, then TypeB
is assignable to TypeA
if…
type TypeA = { name: string; age: number };
type TypeB = { name: string; age: number; gpa: number };
it has at least the same members (properties and property types) as TypeA
.
In other words, TypeB
can have additional properties that aren’t available on TypeA
, but as long as it has the same properties and associated value types as TypeA
, then it is assignable.
*the exception to this rules is with object literalstype Employee = { name: string; age: number };
const jane: Employee = { name: "Jane Smith", age: 30, gpa: 4.0 }; // Type '{ name: string; age: number; gpa: number; }' is not assignable to type 'Employee'.
// Object literal may only specify known properties, and 'gpa' does not exist in type 'Employee'.
In TypeScript, readonly
properties are used to create properties that…
can only be set once during initialization and cannot be modified afterward. Once the value of a readonly property is set, it cannot be changed throughout the object’s lifetime.
Object.freeze()
Takes an object as an argument and freezes it. This prevents the object from being mutated. Any attempts to mutate the object will throw an error at runtime.
What are the characteristics of a ReadonlyArray
?
In TypeScript ReadonlyArray
’s cannot be mutated and do not have the typical array methods available to mutate them such as pop
, push
, and shift
.
Although developers coming from a JavaScript background tend to skip adding readonly to the properties of their types, we would encourage you to think carefully about whether each property’s value should change over the course of a program’s execution. If not, adding readonly will help you uncover and prevent serious issues later on.
What is the purpose of implements
?
In TypeScript, the implements
keyword is used to ensure that a class adheres to the contract defined by an interface. When a class implements an interface, it must provide concrete implementations for all the properties and methods defined in the interface.
Think of implements as a contract between the class definition and the interface. In order to fulfill the contract, you have to explicitly add the correct type information to the properties and methods.
What is private
?
The keyword private
is used to control the visibility of properties and methods within a class hierarchy.
What is a union
type?
A union type is a type formed from two or more other types, representing values that may be any one of those types. We refer to each of these types as the union’s members.
union types in TypeScript allow us to define a type that can hold more than one type
let unionDemo: (number | string) = 'hello';
TypeScript uses a structural typing system. This means…
TypeScript enforces type safety based on the shape of the types rather than their explicit declarations.
What is a type assertion?
Type assertion in TypeScript is a mechanism that allows you to override the inferred type of an expression and specify a different type that you know to be correct. It doesn’t perform any type checking or restructuring of data; it simply tells the TypeScript compiler to treat a value as a particular type. Type assertions are useful when you have more information about the type of a value than TypeScript can infer on its own.
What is a type predicate?
A type predicates is a special return value that allow a developer to create custom type guards.
To define a type predicate we simply define a function whose return type is a type predicate (syntax:[parameterName] is [type]
). When the function returns a truthy value, the TypeScript compiler will determine that the specified argument is of the given type.
the TypeScript compiler does not verify the logic within your type predicate function correctly determines the specified type
What are the five type guards?
typeof
in
truthinessinstanceof
type predicates (custom type guards)