Typescript
tsc filename.ts
: 將ts檔 Compiling to TypeScript, 每次修改完code都要執行一次才會重新 Compilingtsc src/filename.ts
: 如果檔案不在目前terminal所在路徑, 可以再加src路徑, 作用同上tsc filename.ts -w
: 修改完code 會即時將ts檔 Compiling to TypeScript, 可console看即時更新結果
//string, number, boolean
let name:string;
let age: number;
let isOpen: boolean;
//array
let arr1: string[] = []; //array內value只能是string
let arr2: number[] = []; //array內value只能是number
let arr3: any[] = []; //array內value可以是任意型別
//union types
let mixed: (string|number|boolean)[] = []
let uuid: string|number;
uuid = 'emma';
uuid = 123;
//object
//任意物件內容都可以
let obj: object;
obj = {name:'emma', age:123};
//限定物件key與value型別
let objDetail:{
name:string,
age: number,
isDrive: boolean,
};
objDetail = {
name: 'emma',
age: 123,
isDrive: false,
};
// 物件內value型別可以任意
let obj = {name: any, age: any};
obj = {
name: 'emma',
age: 123
};
// 任意型別
let age: any = 25;
age = true;
tsc --init
在src資料夾會出現 tscconfig.json
// tscconfig.json
{
"compilerOption": {
"target": "es6", //指定編譯生成的JS版本
"module": "commonjs", //指定生成哪種模組 ex:es2015
"rootDir": "./src" //.ts檔案所在位置
"outDir": "./public": // .ts要compiler放到哪裡
"forceConsistentCasingInFileNames": true, //強制區分大小寫, 默認為false
"files": ["hello.ts"], //屬性指定要編譯的 TS 檔案
"include": ["src"]或["src/**/*.ts"], //屬性設定編譯時包含哪些檔案或資料夾, 路徑可調整
"exclude": ["node_modules"], //屬性設定編譯時排除哪些檔案或資料夾
},
}
// *-表示匹配0至多個字元(不包含分隔符號)
// ?-匹配一個相符字元(不包含分隔符號)
// **/-表示匹配所有子資料夾
//ps:以下code可以過, 但如果forceConsistentCasingInFileNames為true時,
會報錯誤:'2a' !== '2A'
//2a.ts
export const PI = 3.1415926;
//1a.ts
import PI from './2A.ts';
function fun(){
return PI;
}
tsc -w
在vscode的filename.ts檔案, 下這個指令tsc -w
開啟同步compiler, 當改code的時候, 就會同步輸出js檔, 只要一更改ts就會馬上改js
//宣告型別為 Function
let greet: Function;
greet = () => {
console.log('hello world');
}
//宣告function的參數型別
//有參數c時宣告型別, 並且有 defaultValue 10
const add = (a:number, b:number, c:number | string = 10) => {
console.log(a+b);
console.log(c); //如果沒有= defaultValue 10, log結果為 undefind
}
add(5,10, 'emma');
//有參數c時宣告型別, 且c不能=預設 defaultValue 10
const add = (a:number, b:number, c?:number | string) => {
console.log(a+b);
console.log(c); //如果沒有= defaultValue 10, log結果為 undefind
}
add(5,10, 'emma');
//定義function沒有回傳value: void
const plusFn = (a:number, b: number, c?:number):void =>{
console.log(a+b);
console.log(c);
}
const plusFn = (a:number, b: number, c?:number):number =>{
return a+b+c;
}
//用type宣告型別
type StringOrNum = string|number;
type ObjWithName = {name:string, uid:StringOrNum};
const loginFn = (uid:StringOrNum, name:string) => {
console.log(`${name} has a uid is ${uid}`);
}
const helloFn = (user:ObjWithName) => {
console.log(`${user.name} say hello!`);
}
let greet: Function;
//example1: 宣告greet變數有兩個參數, 並定義型別, 與回傳值型別
let greet: (a:string, b:string) => void;
greet = (name:string, greeting:string):void => {
console.log(`${name} says ${greeting}`);
}
// example2: 如果有宣告回傳值則邏輯結束一定要回傳符合型別的value
let cal: (a:number, b:number, action:string) => number; //回傳number
cal= (a:number, b:number, action:string) => {
//if 沒有else會報錯, 一定要回傳number
if(action === 'add') {
return a+b
}else {
return a-b
}
}
// example3: 參數是物件
let loginFn: (obj: {name: string, age:number}) => void;
type UserType = {name: string, age:number};
loginFn = (user:UserType) => {
console.log(`${user.name} is ${user.age} years old.`);
}
//example1: HTMLFormElement or HTMLAllCollection....等會有提示, 如下:
//<form> id="type"
const form = document.querySelect('.main') as HTMLFormElement;
console.log(form.children);
//example2:
//<select> id="type"
const type = document.querySelect('#type') as HTMLSelectElement;
//<input> id="type"
const type = document.querySelect('#type') as HTMLInputElement;
//<form> id="type"
const type = document.querySelect('#type') as HTMLFormElement;
class Invoice {
readonly client:string; //不管class內外都只能讀, 不能重新assign value
private detail:string; //只能在class裡面access和賦值
public amount:number; //class外也可以access和賦值
constructor(c: string, d: string, a:number){
this.client = c;
this.detail = d;
this.amount = a;
}
//另一種寫法
constructor(
readonly client:string;
private detail:string;
public amount:number;
){}
format(){
// this.client = 'something else' // error, 因為client是readonly不能重新賦值
return `${this.client} owes ${this.detail} for ${this.amount}`
}
}
const invOne = new Invoice('mario', 'work on the mario website', 250);
const invTwo = new Invoice('luigi', 'work on the mario website', 300);
//class就是一種型別
let invoices: Invoice[] = []; //class定義型別
invoices.push(invOne);
invoices.push(invTwo);
invoices.forEach(inv =>{
//因為inv.detail是private所以不能在class外存取, 但可從inv.format()取到detail的值, 因為format()是在class裡面access detail
console.log(inv.client, inv.detail, inv.amount, inv.format());
})
//interface定義型別, 名稱要大寫開頭
interface User {
name: string;
age: number;
speak(a: string): void;
spend(b: number): number;
}
// 宣告userA的型別為User
const userA: User = {
name: 'emma',
age: 123,
speak(text: string):void {
console.log(text);
},
spend(amount: number): number {
console.log(amount);
return amount;
}
}
//用Interfaces宣告function argument 型別範例
const userFn = (users:User) => {
console.log('hello', person.name);
}
userFn(userA); //執行userFn
// src/interfaces/HasFormatter.ts
// 定義format回傳字串
export interfaces HasFormatter {
format(): string;
}
// src/classes/Invoice.ts
import { HasFormatter } from '../interfaces/HasFormatter.ts';
export class Invoice implements HasFormatter {
constructor(
readonly client:string; //不管class內外都只能讀, 不能重新assign value
private detail:string; //只能在class裡面access和賦值
public amount:number; //class外也可以access和賦值
){}
format(){
// this.client = 'something else' // error, 因為client是readonly不能重新賦值
return `${this.client} owes ${this.detail} for ${this.amount}`
}
}
// type
type Dict<T> = {
value: T;
};
// interface
interface WrappedValue<T> {
value: T;
}
// arrow function
const identity = <T>(x: T): T => x;
// function
function identity<T>(x: T): T {
return x;
}
interface Resource<T> {
data: T; //can dynamic defind
uid: number; //repeact use
name: string; //repeact use
errorCode: number; //repeact use
}
const docObj:Resource<object> = {
data: {name: 'emma'};
uid: number;
name: string;
errorCode: number;
}
const docStrArr: Resource<string[]> ={
data: ['emma', 'mark', 'lisa'];
uid: number;
name: string;
errorCode: number;
}
Generic範例: type可以重複使用就看傳入的type是什麼1
Generic範例: type可以重複使用就看傳入的type是什麼2
extends
的使用,可以建立帶有**「限制」**的泛型:
interface WrappedValue<T extends string> {
value: T;
}
// ⭕️ T 滿足 string 的型別
const val: WrappedValue<'Aaron' | 'PJ'> = {
value: 'Aaron',
};
// ❌ T 不滿足 string 時會噴錯
// Type 'number' does not satisfy the constraint 'string'.
const val: WrappedValue<number> = {
value: 30,
};
// ❌ 因為沒有給 T 預設值,所以不能留空
// Generic type 'WrappedValue<T>' requires 1 type argument(s).
const val: WrappedValue = {
value: 30,
};
// 接收 array: T[] 做為參數,回傳 Dictionary {[k: string]: T}
// 若把 T 的限制 { id: number } 拿掉的話,將會沒辦法確定 T 是帶有 id 的物件
const arrayToDict = <T extends { id: number }>(array: T[]): { [k: string]: T } => {
const out: { [k: string]: T } = {};
array.forEach((val) => {
out[val.id] = val;
});
return out;
};
interface WrappedValue<T = string> {
value: T;
}
// 預設 WrappedValue 中使用的型別是 string,但使用者可以改成自己想要使用的
const val: WrappedValue<number> = {
value: 30,
};
這時候,可以透過 extends 限制使用者給定的泛型,例如:
interface WrappedValue<T extends string = string> {
value: T;
}
// 如果沒有提供 `T` 則預設該型別是 `string`
const val: WrappedValue = {
value: 'hello',
};
// ❌ 如果有給 T,但 T 不滿足 string 時,會噴錯
// Type 'number' does not satisfy the constraint 'string'.
const val: WrappedValue<number> = {
value: 30,
};
// ⭕️ 如果有給 T,當 T 滿足 string 時,T 會變成變成實際代表的型別
const val: WrappedValue<'Aaron' | 'PJ'> = {
value: 'Aaron',
};
enum requestStatusCodes {
error = 400,
success = 200,
}
enum requestWrongCodes {
missingParameter = 'A',
wrongParameterType = 'B',
invalidToken = 'C',
}
TypeScript | 善用 Enum 提高程式的可讀性 - 基本用法 feat. JavaScript
let values: [string, string, number]; // defind type
values = [obj.name, obj.address, obj.age]; //declare value
newValues = [...]; // 解壓縮前要defind type才不會報錯
type Data ={
userId: number,
id: number,
title: string,
completed: boolean,
}
async function getData() {
const res = await fetch('https://jsonplaceholder.typicode.com/todo/1');
const data = await res.json() as Data;
}
interface CatInfo {
age: number;
breed: string;
}
type CatName = "miffy" | "boris" | "mordred";
const cats: Record<CatName, CatInfo> = {
miffy: { age: 10, breed: "Persian" },
boris: { age: 5, breed: "Maine Coon" },
mordred: { age: 16, breed: "British Shorthair" },
};
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
};
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
createdAt: 1615544252770,
};
type TodoInfo = Omit<Todo, "completed" | "createdAt">;
const todoInfo: TodoInfo = {
title: "Pick up kids",
description: "Kindergarten closes at 5pm",
};
type UsersDataType = {
data: {
total: number;
users: UserType[];
factories: GroupType[];
departments: GroupType[];
groups: GroupType[];
};
}
type PropType = {
data: UsersDataType;
updateTable: Function;
};
//用在function component的參數方法
const App: React.FC<PropType> = ({data, updateTable}) => {
return<div>首頁</div>
}
軟體開發流程必須要大家有一個共識, 要不然barry會一直用硬體的思維去思考軟體開發, 這樣會一直重工or先後順序不對 軟體界資深的朋友討論, 他們都一致認為我們公司是硬體廠思維, 沒有軟體開發思維很有問題一定要調整 帶領公司從硬體轉到軟體思維, 這會有一個陣痛期, 昨天跟資深軟體工程師討論他們公司的狀況, 不瞞你說他們是科技硬體大廠, 他們也要做軟體轉型, 他們公司投資在轉型這件事已經10年了, 他們的優勢是他們資金夠大可以慢慢調整, 但缺點是因為太大所有轉型雜音很多備受質疑, 但達翔的優勢在於公司規模為中型, 所以調整可以比大型公司較快較有彈性, 但缺點是資金要用在轉型可能資源會比大型公司來得少, 也是因為這樣我想知道barry了解這些背後資源運用跟轉型的痛點到什麼程度?還是說他了解跟實際層面的有落差 畫面的東西沒有跟RD討論就修改, 也不知道對不對的做法會有做白工與溝通上的問題不斷地產生 這點必須要跟PM溝通清楚 修改前會跟RD討論再修改 PM外出事務太多會有無法真實討論畫面問題, 需要與PM討論都找不到人, 並希望PM統一修改畫面而不是大家分著畫, 這個問題點會有多頭馬車,亂掉的問題, PM要明確列表告知RD修改的部分(分成幾點項目這樣), 可以節省掉RD要全部再重新看過設計稿修改也容易造成沒注意到的修改部分(WEI)
Feb 21, 2023服務收費, 每月免費200美金, 超過收費, 信用卡扣款計費方式 路線: 每秒查詢 50 次, Google 地圖平台用量限制 google map aip demo 起始, 終點, 中間增加景點, 自行車模式, 匯入其他人的路徑(array), 匯入會不會有不一樣的路線, 開始導航按鈕, 導航路徑像左轉向右轉前面多遠要爬坡 爬坡路線有幾公尺 爬到一半剩幾公尺 2023/1月開始開發, 2023/6月完成 功能 點擊map取得點擊位置 標上圖釘
Dec 23, 2022menu 南瓜濃湯 炒青椒 炒豆芽+胡蘿蔔 小黃瓜 馬鈴薯泥 芋頭 茄子 燙皇宮菜
Nov 11, 2022HTML & CSS 什麼是 semantic HTML? 使用HTML標記向瀏覽器和開發人員描述它的含義 // non-semantic elements: Tells nothing about its content. <div> and <span> // semantic elements: Clearly defines its content. <form>, <table>, and <article>
Oct 31, 2022or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up