├── .gitignore
├── index.html
├── package-lock.json
├── package.json
├── src
├── app.ts
├── decorators.ts
├── form-namespace.ts
├── generic.ts
└── namespaces.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 | dist
4 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | TypeScript
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-advanced",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "typescript": {
8 | "version": "3.7.3",
9 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz",
10 | "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==",
11 | "dev": true
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-advanced",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "typescript": "^3.7.3"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/app.ts:
--------------------------------------------------------------------------------
1 | // http://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options
2 |
3 | class Person {
4 | constructor(private name: string) {}
5 | }
6 |
7 | const max = new Person('Maxim')
8 |
9 | // Demo comment
10 |
11 | // const btn = document.querySelector('#btn')!
12 | //
13 | // btn.addEventListener('click', () => {
14 | // console.log('Btn clicked!')
15 | // })
16 |
17 | // =======
18 |
19 | let anyFlag
20 |
21 | const globalVar = 'Message'
22 |
23 | function logInfo(data: string, _?: number) {
24 | // const message = 'String'
25 | console.log(data)
26 | anyFlag = true
27 | console.log(anyFlag)
28 | }
29 |
30 | logInfo('I am log string')
31 |
32 | function multiple(a: number, b: number) {
33 | if (a && b) {
34 | return a * b
35 | }
36 | return
37 | }
38 |
--------------------------------------------------------------------------------
/src/decorators.ts:
--------------------------------------------------------------------------------
1 | // function Log(constructor: Function) {
2 | // console.log(constructor)
3 | // }
4 | //
5 | // function Log2(target: any, propName: string | Symbol) {
6 | // console.log(target)
7 | // console.log(propName)
8 | // }
9 | //
10 | // function Log3(target: any, propName: string | Symbol, descriptor: PropertyDescriptor) {
11 | // console.log(target)
12 | // console.log(propName)
13 | // console.log(descriptor)
14 | // }
15 |
16 | // interface ComponentDecorator {
17 | // selector: string
18 | // template: string
19 | // }
20 | //
21 | // function Component(config: ComponentDecorator) {
22 | // return function
23 | //
24 | // (Constructor: T) {
25 | // return class extends Constructor {
26 | // constructor(...args: any[]) {
27 | // super(...args)
28 | //
29 | // const el = document.querySelector(config.selector)!
30 | // el.innerHTML = config.template
31 | // }
32 | // }
33 | // }
34 | // }
35 | //
36 | // function Bind(_: any, _2: any, descriptor: PropertyDescriptor): PropertyDescriptor {
37 | // const original = descriptor.value
38 | //
39 | // return {
40 | // configurable: true,
41 | // enumerable: false,
42 | // get() {
43 | // return original.bind(this)
44 | // }
45 | // }
46 | // }
47 | //
48 | // @Component({
49 | // selector: '#card',
50 | // template: `
51 | //
52 | //
53 | // Card Component
54 | //
55 | //
56 | // `
57 | // })
58 | // class CardComponent {
59 | // constructor(public name: string) {
60 | // }
61 | //
62 | // @Bind
63 | // logName(): void {
64 | // console.log(`Component Name: ${this.name}`)
65 | // }
66 | // }
67 | //
68 | // const card = new CardComponent('My Card Component')
69 | //
70 | // const btn = document.querySelector('#btn')!
71 | //
72 | // btn.addEventListener('click', card.logName)
73 |
74 | // ================
75 |
76 | type ValidatorType = 'required' | 'email'
77 |
78 | interface ValidatorConfig {
79 | [prop: string]: {
80 | [validateProp: string]: ValidatorType
81 | }
82 | }
83 |
84 | const validators: ValidatorConfig = {}
85 |
86 | function Required(target: any, propName: string) {
87 | validators[target.constructor.name] = {
88 | ...validators[target.constructor.name],
89 | [propName]: 'required'
90 | }
91 | }
92 |
93 | function validate(obj: any): boolean {
94 | const objConfig = validators[obj.constructor.name]
95 | if (!objConfig) {
96 | return true
97 | }
98 | let isValid = true
99 | Object.keys(objConfig).forEach(key => {
100 | if (objConfig[key] === 'required') {
101 | isValid = isValid && !!obj[key]
102 | }
103 | })
104 | return isValid
105 | }
106 |
107 | // class Form {
108 | // @Required
109 | // public email: string | void
110 | //
111 | // constructor(email?: string) {
112 | // this.email = email
113 | // }
114 | // }
115 | //
116 | // const form = new Form('v@mail.ru')
117 | //
118 | // if (validate(form)) {
119 | // console.log('Valid: ', form)
120 | // } else {
121 | // console.log('Validation Error')
122 | // }
123 | //
124 |
--------------------------------------------------------------------------------
/src/form-namespace.ts:
--------------------------------------------------------------------------------
1 | namespace Form {
2 | export type FormType = 'inline' | 'block'
3 | export type FormState = 'active' | 'disabled'
4 |
5 | export interface FormInfo {
6 | type: FormType
7 | state: FormState
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/generic.ts:
--------------------------------------------------------------------------------
1 | // const cars: string[] = ['Ford', 'Audi']
2 | // const cars2: Array = ['Ford', 'Audi']
3 |
4 | // const promise: Promise = new Promise(resolve => {
5 | // setTimeout(() => {
6 | // resolve(42)
7 | // }, 2000)
8 | // })
9 | //
10 | // promise.then(data => {
11 | // console.log(data.toFixed())
12 | // })
13 |
14 | function mergeObjects(a: T, b: R) {
15 | return Object.assign({}, a, b)
16 | }
17 |
18 | const merged = mergeObjects({name: 'Vladilen'}, {age: 26})
19 | const merged2 = mergeObjects({model: 'Ford'}, {year: 2010})
20 |
21 | // const merged3 = mergeObjects({a: 1}, 'bbb')
22 | // console.log(merged3)
23 |
24 | // =================
25 |
26 | interface ILength {
27 | length: number
28 | }
29 |
30 | function withCount(value: T): {value: T, count: string} {
31 | return {
32 | value,
33 | count: `В этом объекте ${value.length} символов`
34 | }
35 | }
36 |
37 | // console.log(withCount('Привет typescript'))
38 | // console.log(withCount(['I', 'Am', 'Array']))
39 | // console.log(withCount(20))
40 | // console.log(withCount({length: 20}))
41 |
42 | // ==============
43 |
44 | // function getObjectValue(obj: T, key: R) {
45 | // return obj[key]
46 | // }
47 | //
48 | // const person = {
49 | // name: 'Vladilen',
50 | // age: 26,
51 | // job: 'Javascript'
52 | // }
53 | // console.log(getObjectValue(person, 'name'))
54 | // console.log(getObjectValue(person, 'age'))
55 | // console.log(getObjectValue(person, 'job'))
56 |
57 | // ===============
58 |
59 | class Collection {
60 | constructor(private _items: T[] = []) {}
61 |
62 | add(item: T) {
63 | this._items.push(item)
64 | }
65 |
66 | remove(item: T) {
67 | this._items = this._items.filter(i => i !== item)
68 | }
69 |
70 | get items(): T[] {
71 | return this._items
72 | }
73 | }
74 |
75 | // const strings = new Collection(['I', 'Am', 'Strings'])
76 | // strings.add('!')
77 | // strings.remove('Am')
78 | // console.log(strings.items)
79 | //
80 | // const numbers = new Collection([1, 2, 3])
81 | // numbers.add(2)
82 | // numbers.remove(3)
83 | // console.log(numbers.items)
84 |
85 | // const objs = new Collection([{a: 1}, {b: 2}])
86 | // // objs.remove({b: 2})
87 | // // console.log(objs.items)
88 |
89 | // ===============
90 |
91 | interface Car {
92 | model: string
93 | year: number
94 | }
95 |
96 | function createAndValidateCar(model: string, year: number): Car {
97 | const car: Partial = {}
98 |
99 | if (model.length > 3) {
100 | car.model = model
101 | }
102 |
103 | if (year > 2000) {
104 | car.year = year
105 | }
106 |
107 | return car as Car
108 | }
109 |
110 | ///
111 |
112 | const cars: Readonly> = ['Ford', 'Audi']
113 | // cars.shift()
114 | // cars[1]
115 |
116 | const ford: Readonly = {
117 | model: 'Ford',
118 | year: 2020
119 | }
120 |
121 | // ford.model = 'Ferrari'
122 |
123 |
--------------------------------------------------------------------------------
/src/namespaces.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | namespace Form {
4 | class MyForm {
5 | private type: FormType = 'inline'
6 | private state: FormState = 'active'
7 |
8 | constructor(public email: string) {
9 | }
10 |
11 | getInfo(): FormInfo {
12 | return {
13 | type: this.type,
14 | state: this.state
15 | }
16 | }
17 | }
18 |
19 | export const myForm = new MyForm('v@mail.ru')
20 | }
21 |
22 | console.log(Form.myForm)
23 |
24 | // console.log(myForm)
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | // "incremental": true, /* Enable incremental compilation */
5 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
6 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
7 | // "lib": ["dom", "scripthost", "dom.iterable", "es2016"], /* Specify library files to be included in the compilation. */
8 | // "allowJs": true, /* Allow javascript files to be compiled. */
9 | // "checkJs": true, /* Report errors in .js files. */
10 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
11 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
12 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
13 | "sourceMap": true, /* Generates corresponding '.map' file. */
14 | // "outFile": "./", /* Concatenate and emit output to single file. */
15 | "outDir": "./dist", /* Redirect output structure to the directory. */
16 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
17 | // "composite": true, /* Enable project compilation */
18 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
19 | "removeComments": true, /* Do not emit comments to output. */
20 | // "noEmit": true, /* Do not emit outputs. */
21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
24 | "noEmitOnError": true,
25 |
26 | /* Strict Type-Checking Options */
27 | "strict": true, /* Enable all strict type-checking options. */
28 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
29 | "strictNullChecks": true, /* Enable strict null checks. */
30 | "strictFunctionTypes": true, /* Enable strict checking of function types. */
31 | "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
32 | "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
33 | "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
34 | "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
35 |
36 | /* Additional Checks */
37 | // "noUnusedLocals": true, /* Report errors on unused locals. */
38 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
39 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
40 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
41 |
42 | /* Module Resolution Options */
43 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
44 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
45 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
46 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
47 | // "typeRoots": [], /* List of folders to include type definitions from. */
48 | // "types": [], /* Type declaration files to be included in compilation. */
49 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
50 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
51 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
52 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
53 |
54 | /* Source Map Options */
55 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
56 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
57 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
58 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
59 |
60 | /* Experimental Options */
61 | "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
62 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
63 |
64 | /* Advanced Options */
65 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
66 | }
67 | // "exclude": [
68 | // "./module.ts"
69 | // ]
70 | // "include": [
71 | // "./src/**/*"
72 | // ]
73 | // "files": [
74 | // "./module.ts"
75 | // ]
76 | }
77 |
--------------------------------------------------------------------------------