diff --git a/src/homeworks/ts1/1_base.js b/src/homeworks/ts1/1_base.js deleted file mode 100644 index 611b3a92f..000000000 --- a/src/homeworks/ts1/1_base.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Нужно превратить файл в ts и указать типы аргументов и типы возвращаемого значения - * */ -export const removePlus = (string) => string.replace(/^\+/, ''); - -export const addPlus = (string) => `+${string}`; - -export const removeFirstZeros = (value) => value.replace(/^(-)?[0]+(-?\d+.*)$/, '$1$2'); - -export const getBeautifulNumber = (value, separator = ' ') => - value?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator); - -export const round = (value, accuracy = 2) => { - const d = 10 ** accuracy; - return Math.round(value * d) / d; -}; - -const transformRegexp = - /(matrix\(-?\d+(\.\d+)?, -?\d+(\.\d+)?, -?\d+(\.\d+)?, -?\d+(\.\d+)?, )(-?\d+(\.\d+)?), (-?\d+(\.\d+)?)\)/; - -export const getTransformFromCss = (transformCssString) => { - const data = transformCssString.match(transformRegexp); - if (!data) return { x: 0, y: 0 }; - return { - x: parseInt(data[6], 10), - y: parseInt(data[8], 10), - }; -}; - -export const getColorContrastValue = ([red, green, blue]) => - // http://www.w3.org/TR/AERT#color-contrast - Math.round((red * 299 + green * 587 + blue * 114) / 1000); - -export const getContrastType = (contrastValue) => (contrastValue > 125 ? 'black' : 'white'); - -export const shortColorRegExp = /^#[0-9a-f]{3}$/i; -export const longColorRegExp = /^#[0-9a-f]{6}$/i; - -export const checkColor = (color) => { - if (!longColorRegExp.test(color) && !shortColorRegExp.test(color)) throw new Error(`invalid hex color: ${color}`); -}; - -export const hex2rgb = (color) => { - checkColor(color); - if (shortColorRegExp.test(color)) { - const red = parseInt(color.substring(1, 2), 16); - const green = parseInt(color.substring(2, 3), 16); - const blue = parseInt(color.substring(3, 4), 16); - return [red, green, blue]; - } - const red = parseInt(color.substring(1, 3), 16); - const green = parseInt(color.substring(3, 5), 16); - const blue = parseInt(color.substring(5, 8), 16); - return [red, green, blue]; -}; - -export const getNumberedArray = (arr) => arr.map((value, number) => ({ value, number })); -export const toStringArray = (arr) => arr.map(({ value, number }) => `${value}_${number}`); - -export const transformCustomers = (customers) => { - return customers.reduce((acc, customer) => { - acc[customer.id] = { name: customer.name, age: customer.age, isSubscribed: customer.isSubscribed }; - return acc; - }, {}); -}; diff --git a/src/homeworks/ts1/1_base.test.js b/src/homeworks/ts1/1_base.test.js index ee68dc16f..dbd708234 100644 --- a/src/homeworks/ts1/1_base.test.js +++ b/src/homeworks/ts1/1_base.test.js @@ -1,26 +1,21 @@ -// Этот блок кода удалить и раскомментировать код ниже -it('remove it', () => { - expect(true).toBe(true); -}); +import { transformCustomers } from './1_base'; + +describe('all', () => { + it('transformCustomers', () => { + const customers = [ + { id: 1, name: 'John', age: 25, isSubscribed: true }, + { id: 2, name: 'Mary', age: 40, isSubscribed: false }, + { id: 3, name: 'Bob', age: 32, isSubscribed: true }, + { id: 4, name: 'Alice', age: 22, isSubscribed: true }, + { id: 5, name: 'David', age: 48, isSubscribed: false }, + ]; -// import { transformCustomers } from './1_base'; -// -// describe('all', () => { -// it('transformCustomers', () => { -// const customers = [ -// { id: 1, name: 'John', age: 25, isSubscribed: true }, -// { id: 2, name: 'Mary', age: 40, isSubscribed: false }, -// { id: 3, name: 'Bob', age: 32, isSubscribed: true }, -// { id: 4, name: 'Alice', age: 22, isSubscribed: true }, -// { id: 5, name: 'David', age: 48, isSubscribed: false }, -// ]; -// -// expect(transformCustomers(customers)).toEqual({ -// 1: { name: 'John', age: 25, isSubscribed: true }, -// 2: { name: 'Mary', age: 40, isSubscribed: false }, -// 3: { name: 'Bob', age: 32, isSubscribed: true }, -// 4: { name: 'Alice', age: 22, isSubscribed: true }, -// 5: { name: 'David', age: 48, isSubscribed: false }, -// }); -// }); -// }); + expect(transformCustomers(customers)).toEqual({ + 1: { name: 'John', age: 25, isSubscribed: true }, + 2: { name: 'Mary', age: 40, isSubscribed: false }, + 3: { name: 'Bob', age: 32, isSubscribed: true }, + 4: { name: 'Alice', age: 22, isSubscribed: true }, + 5: { name: 'David', age: 48, isSubscribed: false }, + }); + }); +}); diff --git a/src/homeworks/ts1/1_base.ts b/src/homeworks/ts1/1_base.ts new file mode 100644 index 000000000..c8a3ba0d5 --- /dev/null +++ b/src/homeworks/ts1/1_base.ts @@ -0,0 +1,88 @@ +/** + * Нужно превратить файл в ts и указать типы аргументов и типы возвращаемого значения + * */ +export const removePlus = (string: string): string => string.replace(/^\+/, ''); + +export const addPlus = (string: string): string => `+${string}`; + +export const removeFirstZeros = (value: string): string => value.replace(/^(-)?[0]+(-?\d+.*)$/, '$1$2'); + +export const getBeautifulNumber = (value: string, separator = ' '): string => + value?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator); + +export const round = (value: number, accuracy = 2): number => { + const d = 10 ** accuracy; + return Math.round(value * d) / d; +}; + +const transformRegexp = + /(matrix\(-?\d+(\.\d+)?, -?\d+(\.\d+)?, -?\d+(\.\d+)?, -?\d+(\.\d+)?, )(-?\d+(\.\d+)?), (-?\d+(\.\d+)?)\)/; + +type TransformType = { + x: number; + y: number; +}; + +export const getTransformFromCss = (transformCssString: string): TransformType => { + const data = transformCssString.match(transformRegexp); + if (!data) return { x: 0, y: 0 }; + return { + x: parseInt(data[6], 10), + y: parseInt(data[8], 10), + }; +}; +//кортеж +type Tuple = [number, number, number]; + +export const getColorContrastValue = ([red, green, blue]: Tuple) => + // http://www.w3.org/TR/AERT#color-contrast + Math.round((red * 299 + green * 587 + blue * 114) / 1000); + +export const getContrastType = (contrastValue: number): string => (contrastValue > 125 ? 'black' : 'white'); + +//Type RegExp trivially inferred from a RegExp literal, remove type annotation. +// Тип RegExp не требует явной анотации +export const shortColorRegExp = /^#[0-9a-f]{3}$/i; +export const longColorRegExp = /^#[0-9a-f]{6}$/i; + +export const checkColor = (color: string): void | never => { + if (!longColorRegExp.test(color) && !shortColorRegExp.test(color)) throw new Error(`invalid hex color: ${color}`); +}; + +export const hex2rgb = (color: string): Tuple => { + checkColor(color); + if (shortColorRegExp.test(color)) { + const red = parseInt(color.substring(1, 2), 16); + const green = parseInt(color.substring(2, 3), 16); + const blue = parseInt(color.substring(3, 4), 16); + return [red, green, blue]; + } + const red = parseInt(color.substring(1, 3), 16); + const green = parseInt(color.substring(3, 5), 16); + const blue = parseInt(color.substring(5, 8), 16); + return [red, green, blue]; +}; + +export const getNumberedArray = (arr: Array): { value: T; number: number }[] => + arr.map((value, number) => ({ value, number })); + +export const toStringArray = (arr: { value: string | number; number: string | number }[]): string[] => + arr.map(({ value, number }) => `${value}_${number}`); + +type TCustomer = { + id: number; + name: string; + age: number; + isSubscribed: boolean; +}; + +type TCustomerMap = { + [key: TCustomer['id']]: Omit; +}; + +export const transformCustomers = (customers: Array): TCustomerMap => { + return customers.reduce((acc, customer) => { + acc[customer.id] = { name: customer.name, age: customer.age, isSubscribed: customer.isSubscribed }; + return acc; + }, {}); +}; diff --git a/src/homeworks/ts1/2_repair.ts b/src/homeworks/ts1/2_repair.ts index 19e98c068..c6e973ae1 100644 --- a/src/homeworks/ts1/2_repair.ts +++ b/src/homeworks/ts1/2_repair.ts @@ -2,46 +2,55 @@ * Здесь код с ошибками типов. Нужно их устранить * */ -// // Мы это не проходили, но по тексту ошибки можно понять, как это починить -// export const getFakeApi = async (): void => { -// const result = await fetch('https://jsonplaceholder.typicode.com/todos/1').then((response) => response.json()); -// console.log(result); -// }; -// -// // Мы это не проходили, но по тексту ошибки можно понять, как это починить -// export class SomeClass { -// constructor() { -// this.set = new Set([1]); -// this.channel = new BroadcastChannel('test-broadcast-channel'); -// } -// } -// -// export type Data = { -// type: 'Money' | 'Percent'; -// value: DataValue; -// }; -// -// export type DataValue = Money | Percent; -// -// export type Money = { -// currency: string; -// amount: number; -// }; -// -// export type Percent = { -// percent: number; -// }; -// -// // Здесь, возможно, нужно использовать as, возможно в switch передавать немного по-другому -// const getDataAmount = (data: Data): number => { -// switch (data.type) { -// case 'Money': -// return data.value.amount; -// -// default: { -// // eslint-disable-next-line @typescript-eslint/no-unused-vars -// const unhandled: never = data; // здесь, возможно, нужно использовать нечто другое. :never должен остаться -// throw new Error(`unknown type: ${data.type}`); -// } -// } -// }; +// Мы это не проходили, но по тексту ошибки можно понять, как это починить +export const getFakeApi = async (): Promise => { + const result = await fetch('https://jsonplaceholder.typicode.com/todos/1').then((response) => response.json()); + console.log(result); +}; + +// Мы это не проходили, но по тексту ошибки можно понять, как это починить +export class SomeClass { + private set: Set; + private channel: BroadcastChannel; + constructor() { + this.set = new Set([1]); + this.channel = new BroadcastChannel('test-broadcast-channel'); + } +} + +export type Data = DataMoney | DataPercent; + +type DataMoney = { + type: 'Money'; + value: Money; +}; + +type DataPercent = { + type: 'Percent'; + value: Percent; +}; + +export type DataValue = Money | Percent; + +export type Money = { + currency: string; + amount: number; +}; + +export type Percent = { + percent: number; +}; + +const getDataAmount = (data: Data): number => { + switch (data.type) { + case 'Money': + return data.value.amount; + case 'Percent': + return data.value.percent; + default: { + // Здесь TypeScript должен понимать, что этот код не должен быть достигнут + const unhandled: never = data; // :never должен остаться + throw new Error(`unknown type: ${data}`); + } + } +}; diff --git a/src/homeworks/ts1/3_write.test.js b/src/homeworks/ts1/3_write.test.js index 5b5173063..a11ac89c3 100644 --- a/src/homeworks/ts1/3_write.test.js +++ b/src/homeworks/ts1/3_write.test.js @@ -1,35 +1,30 @@ -// Этот блок кода удалить и раскомментировать код ниже -it('remove it', () => { - expect(true).toBe(true); -}); +import { createRandomOperation, createRandomProduct } from './3_write'; + +describe('all', () => { + it('operation', () => { + const createdAt = '2023-06-06T12:06:56.957Z'; + const operation = createRandomOperation(createdAt); + expect(operation).toHaveProperty('createdAt', createdAt); + expect(operation).toHaveProperty('id'); + expect(operation).toHaveProperty('name'); + expect(operation).toHaveProperty('desc'); + expect(operation).toHaveProperty('createdAt'); + expect(operation).toHaveProperty('amount'); + expect(operation).toHaveProperty('category'); + expect(operation).toHaveProperty('type'); + }); -// import { createRandomOperation, createRandomProduct } from './3_write'; -// -// describe('all', () => { -// it('operation', () => { -// const createdAt = '2023-06-06T12:06:56.957Z'; -// const operation = createRandomOperation(createdAt); -// expect(operation).toHaveProperty('createdAt', createdAt); -// expect(operation).toHaveProperty('id'); -// expect(operation).toHaveProperty('name'); -// expect(operation).toHaveProperty('desc'); -// expect(operation).toHaveProperty('createdAt'); -// expect(operation).toHaveProperty('amount'); -// expect(operation).toHaveProperty('category'); -// expect(operation).toHaveProperty('type'); -// }); -// -// it('product', () => { -// const createdAt = '2023-06-06T12:06:56.957Z'; -// const product = createRandomProduct(createdAt); -// expect(product).toHaveProperty('createdAt', createdAt); -// expect(product).toHaveProperty('id'); -// expect(product).toHaveProperty('name'); -// expect(product).toHaveProperty('photo'); -// expect(product).toHaveProperty('desc'); -// expect(product).toHaveProperty('createdAt'); -// expect(product).toHaveProperty('oldPrice'); -// expect(product).toHaveProperty('price'); -// expect(product).toHaveProperty('category'); -// }); -// }); + it('product', () => { + const createdAt = '2023-06-06T12:06:56.957Z'; + const product = createRandomProduct(createdAt); + expect(product).toHaveProperty('createdAt', createdAt); + expect(product).toHaveProperty('id'); + expect(product).toHaveProperty('name'); + expect(product).toHaveProperty('photo'); + expect(product).toHaveProperty('desc'); + expect(product).toHaveProperty('createdAt'); + expect(product).toHaveProperty('oldPrice'); + expect(product).toHaveProperty('price'); + expect(product).toHaveProperty('category'); + }); +}); diff --git a/src/homeworks/ts1/3_write.ts b/src/homeworks/ts1/3_write.ts index 15f9dcdf2..d45e5cf23 100644 --- a/src/homeworks/ts1/3_write.ts +++ b/src/homeworks/ts1/3_write.ts @@ -5,6 +5,51 @@ * В целом сделайте так, как вам будет удобно. * */ +class Category { + constructor(public id: string, public name: string, public photo?: string) {} +} + +class Product { + constructor( + public id: string, + public name: string, + public photo: string, + public price: number, + public createdAt: string, + public category: Category, + public desc?: string, + public oldPrice?: number + ) {} +} + +class Cost { + constructor( + public id: string, + public name: string, + public amount: number, + public category: Category, + public createdAt: string, + public type: 'Cost', + public desc?: string, + ) { + } +} + +class Profit { + constructor( + public id: string, + public name: string, + public amount: number, + public category: Category, + public createdAt: string, + public type: 'Profit', + public desc?: string, + ) { + } +} + + +type Operation = Cost | Profit; /** * Нужно создать тип Category, он будет использоваться ниже. * Категория содержит @@ -47,10 +92,41 @@ * Создает случайный продукт (Product). * Принимает дату создания (строка) * */ -// export const createRandomProduct = (createdAt: string) => {}; + +export const createRandomProduct = (createdAt: string): Product => { + return new Product( + new Date().toISOString(), + 'Product', + 'https://cs5.pikabu.ru/post_img/big/2015/06/04/11/1433446202_1725992411.jpg', + 100, + createdAt, + new Category(new Date().toISOString(), 'Category') + ); +}; /** * Создает случайную операцию (Operation). * Принимает дату создания (строка) * */ -// export const createRandomOperation = (createdAt: string) => {}; +export const createRandomOperation = (createdAt: string): Operation => { + const randomNumber = Math.floor(+Math.random().toFixed(2)); + if (randomNumber > 0.48) { + return new Cost( + new Date().toISOString(), + 'CostName', + 100, + new Category(new Date().toISOString(), 'Category'), + createdAt, + 'Cost' + ); + } else { + return new Profit( + new Date().toISOString(), + 'ProfitName', + 100, + new Category(new Date().toISOString(), 'Category'), + createdAt, + 'Profit' + ); + } +};