Update sample code

This commit is contained in:
2023-09-25 17:40:50 +07:00
parent 2be0a7f609
commit b1b5c4e16a
4 changed files with 105 additions and 48 deletions
+2 -46
View File
@@ -10,10 +10,6 @@
"license": "ISC",
"dependencies": {
"parcel": "^2.9.3"
},
"devDependencies": {
"@parcel/transformer-typescript-tsc": "^2.9.3",
"typescript": "^5.2.2"
}
},
"node_modules/@babel/code-frame": {
@@ -1423,47 +1419,6 @@
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/transformer-typescript-tsc": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/@parcel/transformer-typescript-tsc/-/transformer-typescript-tsc-2.9.3.tgz",
"integrity": "sha512-kQUts/PVFhEb9JoyJBlKvaa5qR/3bEiyZSjn8qE3S+97CUOIVun8fNxGiDPwpaPd90BgPcgU43gSAQwlY9rIMQ==",
"dev": true,
"dependencies": {
"@parcel/plugin": "2.9.3",
"@parcel/source-map": "^2.1.1",
"@parcel/ts-utils": "2.9.3"
},
"engines": {
"node": ">= 12.0.0",
"parcel": "^2.9.3"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"peerDependencies": {
"typescript": ">=3.0.0"
}
},
"node_modules/@parcel/ts-utils": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/@parcel/ts-utils/-/ts-utils-2.9.3.tgz",
"integrity": "sha512-MiQoXFV8I4IWZT/q5yolKN/gnEY5gZfGB2X7W9WHJbRgyjlT/A5cPERXzVBj6mc3/VM1GdZJz76w637GUcQhow==",
"dev": true,
"dependencies": {
"nullthrows": "^1.1.1"
},
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"peerDependencies": {
"typescript": ">=3.0.0"
}
},
"node_modules/@parcel/types": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.9.3.tgz",
@@ -3286,7 +3241,8 @@
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"devOptional": true,
"optional": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
+5
View File
@@ -7,6 +7,11 @@
</head>
<body>
<h1>Typescript training</h1>
<form>
<input type="text" placeholder="Course title" id="title" />
<input type="text" placeholder="Course price" id="price" />
<button type="submit">Save</button>
</form>
<script type="module" src="index.ts"></script>
</body>
</html>
+91
View File
@@ -126,3 +126,94 @@
// let customer = getCustomer(1);
// console.log(customer?.birthday?.getDate);
// Generics
// function extractAndConvert<T extends object, U extends keyof T>(
// obj: T,
// key: U
// ) {
// return "Value: " + obj[key];
// }
// extractAndConvert({ name: "Max" }, "name");
// class DataStorage<T extends string | number | boolean> {
// private data: T[] = [];
// addItem(item: T) {
// this.data.push(item);
// }
// removeItem(item: T) {
// if (this.data.indexOf(item) === -1) {
// return;
// }
// this.data.splice(this.data.indexOf(item), 1); // -1
// }
// getItems() {
// return [...this.data];
// }
// }
// const textStorage = new DataStorage<string>();
// textStorage.addItem("Max");
// textStorage.addItem("Manu");
// textStorage.removeItem("Max");
// console.log(textStorage.getItems());
// Decorators
const config: { [input: string]: string[] } = {};
const addValidator = (input: string, type: string) => {
config[input] = config[input] ? [...config[input], type] : [type];
console.log(input, type);
};
const Required = (_: any, prop: string) => {
addValidator(prop, "required");
};
const Maxlength = (_: any, prop: string) => addValidator(prop, "maxlength");
const Positive = (_: any, prop: string) => addValidator(prop, "positive");
const validate = (course: any) =>
Object.entries(config).every(([input, types]) =>
types.every(
(type) =>
(type === "required" && course[input]) ||
(type === "positive" && course[input] > 0) ||
(type === "maxlength" && course[input].length < 5)
)
);
class Course {
@Required @Maxlength title: string;
@Required @Positive price: number;
constructor(title: string, price: number) {
this.title = title;
this.price = price;
}
}
const courseForm = document.querySelector("form")!;
courseForm.addEventListener("submit", (event) => {
event.preventDefault();
const titleEl = document.getElementById("title") as HTMLInputElement;
const priceEl = document.getElementById("price") as HTMLInputElement;
const title = titleEl.value;
const price = +priceEl.value;
const createdCourse = new Course(title, price);
if (!validate(createdCourse)) {
alert("Invalid input, please try again!");
return;
}
console.log(createdCourse);
});
console.log(config);
+7 -2
View File
@@ -12,9 +12,14 @@
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"lib": [
"dom",
"ES2017",
"dom.iterable",
"scripthost"
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
"experimentalDecorators": true /* Enable experimental support for legacy experimental decorators. */,
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */