diff --git a/src/homeworks/ts1/1_base.ts b/src/homeworks/ts1/1_base.ts new file mode 100644 index 000000000..60d9ce278 --- /dev/null +++ b/src/homeworks/ts1/1_base.ts @@ -0,0 +1,89 @@ +/** + * Нужно превратить файл в 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: number, separator = ' '): string => + value?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator); + +export const round = (value: number, accuracy: number = 2): number => { + const d = 10 ** accuracy; + return Math.round(value * d) / d; +}; + +const transformRegexp: RegExp = + /(matrix\(-?\d+(\.\d+)?, -?\d+(\.\d+)?, -?\d+(\.\d+)?, -?\d+(\.\d+)?, )(-?\d+(\.\d+)?), (-?\d+(\.\d+)?)\)/; + +type TransformedRegexp = { + x: number; + y: number; +}; + +export const getTransformFromCss = (transformCssString: string): TransformedRegexp => { + const data = transformCssString.match(transformRegexp); + if (!data) return { x: 0, y: 0 }; + return { + x: parseInt(data[6], 10), + y: parseInt(data[8], 10), + }; +}; + +type Colors = [red: number, green: number, blue: number]; + +export const getColorContrastValue = ([red, green, blue]: Colors): number => + // http://www.w3.org/TR/AERT#color-contrast + Math.round((red * 299 + green * 587 + blue * 114) / 1000); + +type BlackOrWhite = 'black' | 'white'; + +export const getContrastType = (contrastValue: number): BlackOrWhite => (contrastValue > 125 ? 'black' : 'white'); + +export const shortColorRegExp: RegExp = /^#[0-9a-f]{3}$/i; +export const longColorRegExp: RegExp = /^#[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): Colors => { + 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]; +}; + +type NumberedArrayItem = { + value: T; + number: number; +}; + +export const getNumberedArray = (arr: T[]): NumberedArrayItem[] => + arr.map((value, number) => ({ value, number })); +export const toStringArray = (arr: NumberedArrayItem[]) => arr.map(({ value, number }) => `${value}_${number}`); + +type Customer = { + id: number; + name: string; + age: number; + isSubscribed: boolean; +}; + +type TransformedCustomer = Record>; + +export const transformCustomers = (customers: Customer[]): TransformedCustomer => { + return customers.reduce((acc: TransformedCustomer, 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..3c9b28d00 100644 --- a/src/homeworks/ts1/2_repair.ts +++ b/src/homeworks/ts1/2_repair.ts @@ -2,46 +2,48 @@ * Здесь код с ошибками типов. Нужно их устранить * */ -// // Мы это не проходили, но по тексту ошибки можно понять, как это починить -// export const getFakeApi = async (): void => { -// const result = await fetch('https://jsonplaceholder.typicode.com/todos/1').then((response) => response.json()); -// console.log(result); -// }; +// Мы это не проходили, но по тексту ошибки можно понять, как это починить +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 { -// 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 class SomeClass { + readonly set: Set; + readonly channel: BroadcastChannel; + constructor() { + this.set = new Set([1]); + this.channel = new BroadcastChannel('test-broadcast-channel'); + } +} + +export type Money = { + currency: string; + amount: number; +}; + +export type Percent = { + percent: number; +}; + +export type DataValue = Money | Percent; + +export type Data = { + type: 'Money' | 'Percent'; + value: DataValue; +}; + +// Здесь, возможно, нужно использовать as, возможно в switch передавать немного по-другому +const getDataAmount = (data: Data): number | never => { + switch (data.type) { + case 'Money': + return (data.value as Money).amount; + + default: { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const unhandled: never = data as never; // здесь, возможно, нужно использовать нечто другое. :never должен остаться + throw new Error(`unknown type: ${data.type}`); + } + } +}; diff --git a/src/homeworks/ts1/3_write.ts b/src/homeworks/ts1/3_write.ts index 15f9dcdf2..d94010070 100644 --- a/src/homeworks/ts1/3_write.ts +++ b/src/homeworks/ts1/3_write.ts @@ -4,6 +4,103 @@ * Поэтому в идеале чтобы функции возвращали случайные данные, но в то же время не абракадабру. * В целом сделайте так, как вам будет удобно. * */ +import crypto from 'crypto'; +import { names, photos, nouns, adjectives } from './data'; + +type Category = { + id: string; + name: string; + photo?: string; +}; + +type Product = { + id: string; + name: string; + photo: string; + desc?: string; + createdAt: string; + oldPrice?: number; + price: number; + category: Category; +}; + +type Operation = Cost | Profit; + +type Cost = { + id: string; + name: string; + desc?: string; + createdAt: string; + amount: number; + category: Category; + type: 'Cost'; +}; + +type Profit = { + id: string; + name: string; + desc?: string; + createdAt: string; + amount: number; + category: Category; + type: 'Profit'; +}; + +const getRandomItemFromArray = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)]; +const getRandomNumber = (min: number, max: number): number => Math.floor(Math.random() * (max - min + 1)) + min; +const getRandomDescription = (nouns: string[], adjectives: string[]): string => { + const fourAdjectives = [...Array(4)].map(() => getRandomItemFromArray(adjectives)).join(' '); + const noun = getRandomItemFromArray(nouns); + return `${fourAdjectives} ${noun}`; +}; +const getRandomId = crypto.randomUUID; +const createRandomCategory = (): Category => ({ + id: getRandomId(), + name: getRandomItemFromArray(names), + photo: getRandomItemFromArray(photos), +}); + +const createRandomCost = (createdAt: string): Cost => ({ + id: getRandomId(), + name: getRandomItemFromArray(names), + desc: getRandomDescription(nouns, adjectives), + createdAt, + amount: getRandomNumber(100, 1000), + category: createRandomCategory(), + type: 'Cost', +}); + +const createRandomProfit = (createdAt: string): Profit => ({ + id: getRandomId(), + name: getRandomItemFromArray(names), + desc: getRandomDescription(nouns, adjectives), + createdAt, + amount: getRandomNumber(100, 1000), + category: createRandomCategory(), + type: 'Profit', +}); + +export const createRandomOperation = (createdAt: string): Operation => { + type OperationsMap = Record Operation>; + const operationsMap: OperationsMap = { + 0: createRandomCost, + 1: createRandomProfit, + }; + const randomNumber = getRandomNumber(0, Object.keys(operationsMap).length - 1); + + return operationsMap[randomNumber](createdAt); +}; + +export const createRandomProduct = (createdAt: string): Product => ({ + id: getRandomId(), + name: getRandomItemFromArray(names), + photo: getRandomItemFromArray(photos), + desc: getRandomDescription(nouns, adjectives), + createdAt, + oldPrice: getRandomNumber(100, 1000), + price: getRandomNumber(100, 1000), + category: createRandomCategory(), +}); /** * Нужно создать тип Category, он будет использоваться ниже. diff --git a/src/homeworks/ts1/data.ts b/src/homeworks/ts1/data.ts new file mode 100644 index 000000000..9bd520d32 --- /dev/null +++ b/src/homeworks/ts1/data.ts @@ -0,0 +1,400 @@ +export const names = [ + 'Emma', + 'Liam', + 'Olivia', + 'Noah', + 'Ava', + 'William', + 'Sophia', + 'James', + 'Isabella', + 'Benjamin', + 'Mia', + 'Lucas', + 'Charlotte', + 'Henry', + 'Amelia', + 'Alexander', + 'Harper', + 'Michael', + 'Evelyn', + 'Ethan', + 'Abigail', + 'Daniel', + 'Ella', + 'Matthew', + 'Avery', + 'Aiden', + 'Scarlett', + 'Jackson', + 'Grace', + 'Logan', + 'Chloe', + 'David', + 'Victoria', + 'Joseph', + 'Riley', + 'Samuel', + 'Aria', + 'Sebastian', + 'Lily', + 'Jack', + 'Zoey', + 'John', + 'Mila', + 'Owen', + 'Layla', + 'Gabriel', + 'Nora', + 'Carter', + 'Ellie', + 'Luke', + 'Madison', + 'Anthony', + 'Hazel', + 'Isaac', + 'Aurora', + 'Dylan', + 'Penelope', + 'Wyatt', + 'Lillian', + 'Andrew', + 'Addison', + 'Joshua', + 'Lucy', + 'Christopher', + 'Hannah', + 'Grayson', + 'Stella', + 'Jack', + 'Natalie', + 'Julian', + 'Leah', + 'Ryan', + 'Violet', + 'Jaxon', + 'Savannah', + 'Levi', + 'Audrey', + 'Nathan', + 'Brooklyn', + 'Caleb', + 'Bella', + 'Christian', + 'Claire', + 'Hunter', + 'Skylar', + 'Eli', + 'Samantha', + 'Isaiah', + 'Paisley', + 'Thomas', + 'Kennedy', + 'Charles', + 'Ellie', + 'Aaron', + 'Peyton', + 'Lincoln', + 'Mila', + 'Adrian', + 'Sophie', + 'Jonathan', +]; + +export const photos = [ + 'https://example.com/page1', + 'https://example.com/page2', + 'https://example.com/page3', + 'https://example.com/page4', + 'https://example.com/page5', + 'https://example.com/page6', + 'https://example.com/page7', + 'https://example.com/page8', + 'https://example.com/page9', + 'https://example.com/page10', + 'https://example.com/page11', + 'https://example.com/page12', + 'https://example.com/page13', + 'https://example.com/page14', + 'https://example.com/page15', + 'https://example.com/page16', + 'https://example.com/page17', + 'https://example.com/page18', + 'https://example.com/page19', + 'https://example.com/page20', + 'https://example.com/page21', + 'https://example.com/page22', + 'https://example.com/page23', + 'https://example.com/page24', + 'https://example.com/page25', + 'https://example.com/page26', + 'https://example.com/page27', + 'https://example.com/page28', + 'https://example.com/page29', + 'https://example.com/page30', + 'https://example.com/page31', + 'https://example.com/page32', + 'https://example.com/page33', + 'https://example.com/page34', + 'https://example.com/page35', + 'https://example.com/page36', + 'https://example.com/page37', + 'https://example.com/page38', + 'https://example.com/page39', + 'https://example.com/page40', + 'https://example.com/page41', + 'https://example.com/page42', + 'https://example.com/page43', + 'https://example.com/page44', + 'https://example.com/page45', + 'https://example.com/page46', + 'https://example.com/page47', + 'https://example.com/page48', + 'https://example.com/page49', + 'https://example.com/page50', + 'https://example.com/page51', + 'https://example.com/page52', + 'https://example.com/page53', + 'https://example.com/page54', + 'https://example.com/page55', + 'https://example.com/page56', + 'https://example.com/page57', + 'https://example.com/page58', + 'https://example.com/page59', + 'https://example.com/page60', + 'https://example.com/page61', + 'https://example.com/page62', + 'https://example.com/page63', + 'https://example.com/page64', + 'https://example.com/page65', + 'https://example.com/page66', + 'https://example.com/page67', + 'https://example.com/page68', + 'https://example.com/page69', + 'https://example.com/page70', + 'https://example.com/page71', + 'https://example.com/page72', + 'https://example.com/page73', + 'https://example.com/page74', + 'https://example.com/page75', + 'https://example.com/page76', + 'https://example.com/page77', + 'https://example.com/page78', + 'https://example.com/page79', + 'https://example.com/page80', + 'https://example.com/page81', + 'https://example.com/page82', + 'https://example.com/page83', + 'https://example.com/page84', + 'https://example.com/page85', + 'https://example.com/page86', + 'https://example.com/page87', + 'https://example.com/page88', + 'https://example.com/page89', + 'https://example.com/page90', + 'https://example.com/page91', + 'https://example.com/page92', + 'https://example.com/page93', + 'https://example.com/page94', + 'https://example.com/page95', + 'https://example.com/page96', + 'https://example.com/page97', + 'https://example.com/page98', + 'https://example.com/page99', + 'https://example.com/page100', +]; + +export const adjectives = [ + 'happy', + 'sad', + 'angry', + 'excited', + 'bored', + 'tired', + 'energetic', + 'calm', + 'anxious', + 'brave', + 'curious', + 'daring', + 'eager', + 'fearful', + 'gentle', + 'honest', + 'jolly', + 'kind', + 'lazy', + 'mysterious', + 'nervous', + 'optimistic', + 'pessimistic', + 'quiet', + 'restless', + 'silly', + 'thoughtful', + 'upbeat', + 'victorious', + 'witty', + 'zealous', + 'adventurous', + 'bold', + 'cheerful', + 'determined', + 'elegant', + 'friendly', + 'graceful', + 'humble', + 'intelligent', + 'joyful', + 'keen', + 'loyal', + 'modest', + 'noble', + 'outgoing', + 'polite', + 'quick', + 'reliable', + 'sincere', + 'trustworthy', + 'understanding', + 'vibrant', + 'wise', + 'youthful', + 'zany', + 'ambitious', + 'brilliant', + 'creative', + 'diligent', + 'enthusiastic', + 'forgiving', + 'generous', + 'helpful', + 'imaginative', + 'jovial', + 'knowledgeable', + 'loving', + 'motivated', + 'neat', + 'observant', + 'patient', + 'quirky', + 'respectful', + 'supportive', + 'talented', + 'unique', + 'versatile', + 'warm', + 'xenial', + 'yielding', + 'zealous', + 'affectionate', + 'bright', + 'courageous', + 'dependable', + 'empathetic', + 'faithful', + 'gentle', + 'hardworking', + 'innovative', + 'jubilant', + 'kindhearted', + 'likable', + 'mindful', + 'nurturing', + 'optimistic', + 'persistent', + 'resourceful', + 'sensible', +]; +export const nouns = [ + 'apple', + 'banana', + 'car', + 'dog', + 'elephant', + 'flower', + 'guitar', + 'house', + 'island', + 'jacket', + 'kite', + 'lamp', + 'mountain', + 'notebook', + 'ocean', + 'pencil', + 'queen', + 'river', + 'sun', + 'tree', + 'umbrella', + 'vase', + 'whale', + 'xylophone', + 'yacht', + 'zebra', + 'airplane', + 'book', + 'cat', + 'door', + 'engine', + 'forest', + 'garden', + 'hat', + 'ice', + 'jungle', + 'key', + 'lion', + 'moon', + 'nest', + 'orange', + 'piano', + 'quilt', + 'road', + 'star', + 'train', + 'unicorn', + 'violin', + 'window', + 'x-ray', + 'yogurt', + 'zoo', + 'ant', + 'ball', + 'cake', + 'desk', + 'egg', + 'fish', + 'goat', + 'hill', + 'igloo', + 'jewel', + 'kangaroo', + 'leaf', + 'mirror', + 'net', + 'owl', + 'pizza', + 'quill', + 'ring', + 'ship', + 'table', + 'umbrella', + 'village', + 'water', + 'xenon', + 'yarn', + 'zinc', + 'arch', + 'bridge', + 'cloud', + 'drum', + 'earth', + 'feather', + 'glove', + 'hammer', + 'ink', + 'jigsaw', + 'kite', + 'ladder', +];