-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathassessment.ts
More file actions
273 lines (227 loc) · 8.32 KB
/
Copy pathassessment.ts
File metadata and controls
273 lines (227 loc) · 8.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
class CustomError extends Error {
constructor(message: string) {
super(message);
this.name = 'CustomError';
}
}
async function typescriptIsAwesome() {
// Implicit any and type inference issues
let implicitAny; // No type specified, implicitly any
implicitAny = 10;
console.log(`Implicit any type: ${implicitAny}`);
implicitAny = "Now I'm a string!";
console.log(`Implicit any type changed: ${implicitAny}`);
// Handling null and undefined
let nullableValue: string | null = null;
console.log(`Nullable value: ${nullableValue}`);
nullableValue = "Now I'm not null!";
console.log(`Nullable value: ${nullableValue}`);
let undefinedValue: string | undefined;
console.log(`Undefined value: ${undefinedValue}`);
// Using any type
let anyValue: any = 42;
console.log(`Any type: ${anyValue}`);
anyValue = "Now I'm a string!";
console.log(`Any type changed: ${anyValue}`);
// Array out of bounds
let arr = [1, 2, 3];
console.log(`Array element: ${arr[3]}`); // Undefined, no runtime error
// Exception handling, because who needs structured error management?
try {
throw new CustomError("Something went wrong");
} catch (e) {
if (e instanceof CustomError) {
console.log(`Encountered a custom error: ${e.message}`);
}
}
// Async/await pitfalls
async function asyncFunction() {
return "Hello, async!";
}
async function withAwait() {
console.log("Before await");
const result = await asyncFunction();
console.log(`Result: ${result}`);
console.log("After await");
}
withAwait().catch(e => console.error(e));
// This binding issues
class MyClass {
value = 42;
getValue() {
return this.value;
}
}
const instance = new MyClass();
const unboundGetValue = instance.getValue;
try {
console.log(`Unbound this value: ${unboundGetValue()}`); // Undefined or throws error
} catch (e) {
console.log("Caught unbound this error");
}
// Type assertion pitfalls
let someValue: unknown = "This is a string";
let strLength: number = (someValue as string).length;
console.log(`String length: ${strLength}`);
// Enum pitfalls
enum Color {
Red,
Green,
Blue
}
let color: Color = Color.Green;
console.log(`Enum value: ${color}`);
color = 3; // No error, but invalid enum value
console.log(`Invalid enum value: ${color}`);
// Implicit conversions and coercions
let num: number = 10;
let str: string = "5";
let coercedResult = num + str;
console.log(`Implicit conversion result: ${coercedResult}`); // Concatenates to "105"
// TypeScript quirks with type guards
function isString(value: any): value is string {
return typeof value === 'string';
}
let unknownValue: unknown = "Hello, world!";
if (isString(unknownValue)) {
console.log(`String value: ${unknownValue}`);
} else {
console.log("Value is not a string");
}
// Type mismatch issues
let numberArray: number[] = [1, 2, 3];
let mixedArray: (number | string)[] = numberArray; // Allowed, but can cause issues
mixedArray.push("A string!");
console.log(`Mixed array: ${mixedArray}`);
// Non-null assertion operator pitfalls
let nullableStr: string | null = null;
try {
console.log(`Non-null asserted string length: ${nullableStr!.length}`); // Runtime error
} catch (e) {
console.log("Caught a runtime error due to non-null assertion operator on null");
}
// Complex type inference issues
function complexTypeInference<T>(x: T) {
return [x, x];
}
let inferredValue = complexTypeInference("hello");
console.log(`Complex type inference: ${inferredValue}`);
// Namespace and module pitfalls
namespace MyNamespace {
export class MyClass {
greet() {
return "Hello from namespace!";
}
}
}
const namespacedInstance = new MyNamespace.MyClass();
console.log(namespacedInstance.greet());
// Decorator usage pitfalls
function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with arguments: ${JSON.stringify(args)}`);
return originalMethod.apply(this, args);
};
return descriptor;
}
class DecoratedClass {
@logMethod
decoratedMethod(arg: string) {
return `Argument was: ${arg}`;
}
}
const decoratedInstance = new DecoratedClass();
console.log(decoratedInstance.decoratedMethod("test"));
// Generic type pitfalls
function genericFunction<T>(arg: T): T {
return arg;
}
let genericValue = genericFunction<string>("Hello, generics!");
console.log(`Generic function: ${genericValue}`);
// Mixins and multiple inheritance issues
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null)
);
});
});
}
class CanEat {
eat() {
console.log("Eating...");
}
}
class CanSleep {
sleep() {
console.log("Sleeping...");
}
}
class Human implements CanEat, CanSleep {
eat!: () => void;
sleep!: () => void;
}
applyMixins(Human, [CanEat, CanSleep]);
const human = new Human();
human.eat();
human.sleep();
// Advanced async/await issues
async function advancedAsyncFunction() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Async result"), 1000);
});
}
async function runAdvancedAsync() {
console.log("Before advanced await");
const result = await advancedAsyncFunction();
console.log(`Advanced async result: ${result}`);
console.log("After advanced await");
}
runAdvancedAsync().catch(e => console.error(e));
// Conditional types pitfalls
type MessageOf<T> = T extends { message: unknown } ? T["message"] : never;
type ErrorMessage = MessageOf<CustomError>; // Expected string
console.log("Conditional types: ", typeof ErrorMessage);
// Recursive type definitions pitfalls
type NestedNumbers = number | NestedNumbers[];
let nestedNumber: NestedNumbers = [1, [2, [3, 4]], 5];
console.log(`Recursive type definition: ${nestedNumber}`);
// Excessive type assertions
let excessiveAssertions: any = "Hello, world!";
console.log(`Excessive assertions: ${((excessiveAssertions as number) as boolean) as string}`);
// Type narrowing pitfalls
function typeNarrowing(value: string | number) {
if (typeof value === 'string') {
console.log(`Type narrowed to string: ${value}`);
} else if (typeof value === 'number') {
console.log(`Type narrowed to number: ${value}`);
} else {
console.log(`Type not narrowed properly: ${value}`);
}
}
typeNarrowing(10);
typeNarrowing("Hello");
typeNarrowing(true as any); // Improper type narrowing
// Module resolution issues
// import { SomeModule } from 'some-nonexistent-module'; // This will cause module resolution error
// Exhaustiveness checking issues
type Fruit = 'Apple' | 'Banana' | 'Orange';
function getFruitName(fruit: Fruit): string {
switch (fruit) {
case 'Apple':
return 'Apple';
case 'Banana':
return 'Banana';
default:
const exhaustiveCheck: never = fruit; // Should catch exhaustiveness issues
return exhaustiveCheck; // This will cause an error if not exhaustive
}
}
console.log(`Exhaustiveness checking: ${getFruitName('Apple')}`);
console.log("End of wildly awesome function.");
}
typescriptIsAwesome().catch(e => console.error(`Unhandled error: ${e.message}`));