Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.exclude": {
"**/node_modules": false,
}
}
10 changes: 8 additions & 2 deletions exercises/exercise-00/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ Run this exercise:

*/

const users: unknown[] = [
interface Users {
name: string,
age: number,
occupation: string
}

const users: Users[] = [
{
name: 'Max Mustermann',
age: 25,
Expand All @@ -39,7 +45,7 @@ const users: unknown[] = [
}
];

function logPerson(user: unknown) {
function logPerson(user: Users) {
console.log(` - ${chalk.green(user.name)}, ${user.age}`);
}

Expand Down
6 changes: 4 additions & 2 deletions exercises/exercise-01/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ interface Admin {
role: string;
}

const persons: User[] /* <- Person[] */ = [
type Person = User | Admin;

const persons: Person[] = [
{
name: 'Max Mustermann',
age: 25,
Expand All @@ -63,7 +65,7 @@ const persons: User[] /* <- Person[] */ = [
}
];

function logPerson(user: User) {
function logPerson(user: Person) {
console.log(` - ${chalk.green(user.name)}, ${user.age}`);
}

Expand Down
2 changes: 1 addition & 1 deletion exercises/exercise-02/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const persons: Person[] = [

function logPerson(person: Person) {
let additionalInformation: string;
if (person.role) {
if ('role' in person) {
additionalInformation = person.role;
} else {
additionalInformation = person.occupation;
Expand Down
4 changes: 2 additions & 2 deletions exercises/exercise-03/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ const persons: Person[] = [
{ type: 'admin', name: 'Bruce Willis', age: 64, role: 'World saver' }
];

function isAdmin(person: Person) {
function isAdmin(person: Person): person is Admin{
return person.type === 'admin';
}

function isUser(person: Person) {
function isUser(person: Person): person is User {
return person.type === 'user';
}

Expand Down
4 changes: 3 additions & 1 deletion exercises/exercise-04/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ interface Admin {

type Person = User | Admin;

type PartialUser = Partial<User>;

const persons: Person[] = [
{ type: 'user', name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' },
{
Expand Down Expand Up @@ -95,7 +97,7 @@ function logPerson(person: Person) {
console.log(` - ${chalk.green(person.name)}, ${person.age}, ${additionalInformation}`);
}

function filterUsers(persons: Person[], criteria: User): User[] {
function filterUsers(persons: Person[], criteria: PartialUser): User[] {
return persons.filter(isUser).filter((user) => {
let criteriaKeys = Object.keys(criteria) as (keyof User)[];
return criteriaKeys.every((fieldName) => {
Expand Down
12 changes: 10 additions & 2 deletions exercises/exercise-05/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ interface Admin {

type Person = User | Admin;

type FilterCriteria<T> = Partial<Omit<T, 'type'>>;

const persons: Person[] = [
{ type: 'user', name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' },
{ type: 'admin', name: 'Jane Doe', age: 32, role: 'Administrator' },
Expand All @@ -64,11 +66,17 @@ function logPerson(person: Person) {
);
}

function filterPersons(persons: Person[], personType: string, criteria: unknown): unknown[] {
function getObjectKeys<O>(obj: O): (keyof O)[] {
return Object.keys(obj) as (keyof O)[];
}

function filterPersons(persons: Person[], personType: 'user', criteria: FilterCriteria<User>): User[];
function filterPersons(persons: Person[], personType: 'admin', criteria: FilterCriteria<Admin>): Admin[];
function filterPersons(persons: Person[], personType: 'user' | 'admin', criteria: FilterCriteria<Person>): Person[] {
return persons
.filter((person) => person.type === personType)
.filter((person) => {
let criteriaKeys = Object.keys(criteria) as (keyof Person)[];
let criteriaKeys = getObjectKeys(criteria);
return criteriaKeys.every((fieldName) => {
return person[fieldName] === criteria[fieldName];
});
Expand Down
2 changes: 1 addition & 1 deletion exercises/exercise-06/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ const users: User[] = [
}
];

function swap(v1, v2) {
function swap<T1, T2>(v1: T1, v2: T2) : [T2, T1] {
return [v2, v1];
}

Expand Down
4 changes: 2 additions & 2 deletions exercises/exercise-07/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ interface Admin {
role: string;
}

type PowerUser = unknown;
type PowerUser = Omit<User & Admin, 'type'> & { type: 'powerUser' };

type Person = User | Admin | PowerUser;

Expand Down Expand Up @@ -99,4 +99,4 @@ console.log(chalk.yellow('Power users:'));
persons.filter(isPowerUser).forEach(logPerson);

// In case if you are stuck:
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#predefined-conditional-types
// https://www.typescriptlang.org/docs/handbook/utility-types.html
25 changes: 7 additions & 18 deletions exercises/exercise-08/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,50 +63,39 @@ const users: User[] = [
{ type: 'user', name: 'Kate Müller', age: 23, occupation: 'Astronaut' }
];

type AdminsApiResponse = (
type ApiResponse<T> = (
{
status: 'success';
data: Admin[];
data: T;
} |
{
status: 'error';
error: string;
}
);
)

function requestAdmins(callback: (response: AdminsApiResponse) => void) {
function requestAdmins(callback: (response: ApiResponse<Admin[]>) => void) {
callback({
status: 'success',
data: admins
});
}

type UsersApiResponse = (
{
status: 'success';
data: User[];
} |
{
status: 'error';
error: string;
}
);

function requestUsers(callback: (response: UsersApiResponse) => void) {
function requestUsers(callback: (response: ApiResponse<User[]>) => void) {
callback({
status: 'success',
data: users
});
}

function requestCurrentServerTime(callback: (response: unknown) => void) {
function requestCurrentServerTime(callback: (response: ApiResponse<number>) => void) {
callback({
status: 'success',
data: Date.now()
});
}

function requestCoffeeMachineQueueLength(callback: (response: unknown) => void) {
function requestCoffeeMachineQueueLength(callback: (response: ApiResponse<string>) => void) {
callback({
status: 'error',
error: 'Numeric value has exceeded Number.MAX_SAFE_INTEGER.'
Expand Down
15 changes: 13 additions & 2 deletions exercises/exercise-09/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,19 @@ type ApiResponse<T> = (
}
);

function promisify(arg: unknown): unknown {
return null;
type PromisifyOldDefinition<T> = (callback: (response: ApiResponse<T>) => void) => void;
type PromisifyNewDefinition<T> = () => Promise<T>;

function promisify<T>(oldFunction: PromisifyOldDefinition<T>): PromisifyNewDefinition<T> {
return () => new Promise((resolve, reject) => {
oldFunction((response) => {
if (response.status === 'success') {
resolve(response.data)
} else {
reject(response.error)
}
});
});
}

const oldApi = {
Expand Down
7 changes: 5 additions & 2 deletions exercises/exercise-10/declarations/str-utils/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
declare module 'str-utils' {
// export const ...
// export function ...
export function strToLower(str: string): string;
export function strToUpper(str: string): string;
export function strReverse(str: string): string;
export function strInvertCase(str: string): string;
export function strRandomize(str: string): string;
}
12 changes: 11 additions & 1 deletion exercises/exercise-11/declarations/stats/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
declare module 'stats' {
export function getMaxIndex(input: unknown, comparator: unknown): unknown;
type Comparator<I> = (a: I, b: I) => number;
type StatIndexFunction = <I>(input: I[], comparator: Comparator<I>) => number;
type StatElementFunction = <I>(input: I[], comparator: Comparator<I>) => I;

export const getMaxIndex: StatIndexFunction;
export const getMinIndex: StatIndexFunction;
export const getMedianIndex: StatIndexFunction;
export const getMaxElement: StatElementFunction;
export const getMinElement: StatElementFunction;
export const getMedianElement: StatElementFunction;
export const getAverageValue: <I, O>(items: I[], getValue: (item: I) => O) => O;
}
2 changes: 1 addition & 1 deletion exercises/exercise-11/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Exercise:
Provide type declaration for that module in:
declarations/stats/index.d.ts

Higher difficulty bonus excercise:
Higher difficulty bonus exercise:

Avoid duplicates of type declarations.

Expand Down
2 changes: 1 addition & 1 deletion exercises/exercise-11/node_modules/stats/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
import 'date-wizard';

declare module 'date-wizard' {
// Add your module extensions here.
interface DateDetails {
hours: number;
minutes: number;
seconds: number;
}
export function pad(num: number): string;
}
Loading