Open ltnhan04 opened 1 month ago
console.log("Hello! Typescript");
// **Implicit Types**
let helloWorld = "Hello, Word!";
// **Explicit types**
let firstName: string = "name";
let age: number = 20;
/**
Built-in Types
Boolean
Number
String
Array
Tuple
Enum
Unknown
Any
Void
Null and Undefined
*/
// **Tuple**
type stringAndNumber = [string, number];
let x: stringAndNumber = ["Hello", 10];
// **Enums**
enum Continents {
North_America, //0
South_America, //1
Africa,
Asia,
Europe,
Antarctica,
Australia,
}
// **Usage**
var region = Continents.Africa; //2
// **Interface**
interface User {
name: string;
id: number;
}
const user: User = {
name: "Nhan",
id: 0,
};
// **Composing types --> Union**
type WindowStates = "open" | "closed" | "minimized";
type oddNumber = 1 | 3 | 5 | 7;
const odd: oddNumber = 5;
const getLength = (param: string | string[]) => {
return param.length;
};
getLength("test");
getLength(["test", "test1"]);
// **Type Inference**
enum CounterActionType {
Increment = "INCREMENT",
IncrementByAction = "INCREMENT_BY",
}
interface IncrementAction {
type: CounterActionType.Increment;
}
interface IncrementByAction {
type: CounterActionType.IncrementByAction;
payload: number;
}
type CounterAction = IncrementAction | IncrementByAction;
const reducer = (state: number, action: CounterAction) => {
switch (action.type) {
case CounterActionType.Increment:
return state + 1;
case CounterActionType.IncrementByAction:
return state + action.payload;
default:
return state;
}
};
// **Literal Types**
// Instead
// type Review = 1 | 2 | 3 | 4 | 5;
// or better yet:
const reviewMap = {
terrible: 1,
average: 2,
good: 3,
great: 4,
incredible: 5,
} as const;
// This is generate the same type as above
// but it's much more maintainable
type Review = (typeof reviewMap)[keyof typeof reviewMap];
// **Index Signatures**
enum ParticipationStatus {
Joined = "JOINED",
Left = "LEFT",
Pending = "PENDING",
}
interface ParticipantData {
[id: string]: ParticipationStatus;
}
const participant: ParticipantData = {
id1: ParticipationStatus.Joined,
};
// **Generics**
const clone = <T>(object: T) => {
const clonedObject: T = JSON.parse(JSON.stringify(object));
return clonedObject;
};
const obj = {
a: 1,
b: {
c: 3,
},
};
const obj2 = clone(obj);
// **Immutable Types**
const ErrorMessages = {
InvalidEmail: "Invalid email",
InvalidPassword: "Invalid password",
// ...
} as const;
// This will throw an error
ErrorMessages.InvalidEmail = "New error message";
// **Partial, Pick, Omit & Required Types**
interface User {
name: string;
age?: number;
email: string;
}
type PartialUser = Partial<User>;
type PickUser = Pick<User, "name" | "age">;
type OmitUser = Omit<User, "age">;
type RequiredUser = Required<User>;
// **PartialUser** is equivalent to:
// interface PartialUser {
// name?: string;
// age?: number;
// email?: string;
// }
// **PickUser** is equivalent to:
// interface PickUser {
// name: string;
// age?: number;
// }
// **OmitUser** is equivalent to:
// interface OmitUser {
// name: string;
// email: string;
// }
// **RequiredUser** is equivalent to:
// interface RequiredUser {
// name: string;
// age: number;
// email: string;
// }
// **Intersection**
type A = B & C;
// **Initial Types**
// Type cho Props của Component:
interface ButtonProps {
label: string;
onClick: () => void;
}
const Button: React.FC<ButtonProps> = ({ label, onClick }) => (
<button onClick={onClick}>{label}</button>
);
// Type cho State:
const [count, setCount] = React.useState<number>(0);
// Type cho các Hook:
const countRef = React.useRef<number>(0);
// Type cho Event Handlers:
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
console.log('Button clicked');
};
// Type cho Context:
interface AuthContextType {
user: string | null;
login: (username: string) => void;
logout: () => void;
}
const AuthContext = React.createContext<AuthContextType | undefined>(undefined);
// Type cho các Hàm:
const add = (a: number, b: number): number => {
return a + b;
};
// Type cho Component với React.FC:
const MyComponent: React.FC = ({ children }) => {
return <div>{children}</div>;
};
// Type cho Redux (nếu sử dụng Redux):
interface AppState {
counter: number;
}
const selectCounter = (state: AppState) => state.counter;
// Type cho các API Request/Response:
interface User {
id: number;
name: string;
email: string;
}
const fetchUser = async (id: number): Promise<User> => {
const response = await fetch(`/api/users/${id}`);
return response.json();
};
// Type cho Optional Props:
interface UserProps {
name: string;
age?: number; // Tuỳ chọn
}
Git Commit Message and Branch Naming Guidelines
General Rules
main
branch. Always create a new branch for your work.Commit Message Structure
Format:
<type>: <description>
feat: add email notifications for new messages
Types:
feat(feature)
: A new feature.fix(fix bug)
: A bug fix.docs(documents)
: Documentation updates.style
: UI styling changes.refactor
: Code refactoring, such as renaming functions or variables, or removing unused code.perf
: Performance improvements.test
: Adding or updating test cases, fixing unit tests, etc.Description:
Branch Naming Convention
Prefix the branch name based on the type of work:
feature/
: For new features.bugfix/
: For bug fixes.hotfix/
: For critical bug fixes.docs/
: For documentation updates.Example:
feature/new-feature