Complete TypeScript JavaScript Symbols Guide From Basics to Advanced Usage

In TypeScript and JavaScript development, various punctuation symbols are not only components of syntax, but also important tools for expressing complex logic. This article will provide a detailed introduction to each symbol’s usage from basic to advanced levels, combined with practical application scenarios in the React and TanStack ecosystem.

Table of Contents

Basic Assignment and String Symbols

Equal Sign = - The Art of Assignment

Basic Usage

1
2
3
4
5
6
7
// Simple assignment
let userName = "Alice";
const PI = 3.14159;

// Destructuring assignment
const { data, error } = useQuery();
const [count, setCount] = useState(0);

Advanced Applications in React

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// useState state updates
const [user, setUser] = useState<User | null>(null);

// useReducer action handling
const [state, dispatch] = useReducer(reducer, initialState);

// Component props destructuring
const MyComponent = ({ title, onSubmit, children }: Props) => {
return <div>{title}</div>;
};

// The above component props destructuring is equivalent to:
// const MyComponent = (props: Props) => {
// const { title, onSubmit, children } = props;
// return <div>{title}</div>;
// };

Applications in TanStack Query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Query result destructuring
const { data: users, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});

// Mutation operations
const mutation = useMutation({
mutationFn: updateUser,
onSuccess: (data) => {
// data is the returned result
setUser(data);
},
});

Quote Family: " ' ` - Three Realms of Strings

Double Quotes " and Single Quotes '

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Basic strings
const message = "Hello World";
const name = 'React Developer';

// Usage in JSX attributes
<button className="btn-primary" onClick={handleClick}>
Submit
</button>

// JSON data (must use double quotes)
const config = {
"apiUrl": "https://api.example.com",
"timeout": 5000
};

Backticks ` - Powerful Template Strings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Basic template strings
const greeting = `Hello, ${userName}!`;

// Multi-line strings
const sqlQuery = `
SELECT id, name, email
FROM users
WHERE active = true
ORDER BY created_at DESC
`;

// Dynamic styles in React
const containerStyle = {
backgroundColor: `hsl(${hue}, 70%, 50%)`,
transform: `translateX(${offset}px)`
};

// Dynamic query keys in TanStack Query
const queryKey = ['user', userId, `profile-${version}`];

Advanced Template String Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Tagged template strings (for styling libraries like styled-components)
const StyledButton = styled.button`
background: ${props => props.primary ? 'blue' : 'white'};
color: ${props => props.primary ? 'white' : 'blue'};
padding: ${({ size }) => size === 'large' ? '12px 24px' : '8px 16px'};
`;

// GraphQL queries (common in TanStack projects)
const GET_USERS = gql`
query GetUsers($limit: Int!) {
users(limit: $limit) {
id
name
email
}
}
`;

Object and Type System Symbols

Colon : - Bridge Between Types and Values

Object Property Definition

1
2
3
4
5
const user = {
name: "张三",
age: 25,
hobbies: ["reading", "coding"]
};

TypeScript Type Annotations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Basic type annotations
let count: number = 0;
let message: string = "Hello";
let isActive: boolean = true;

// Function type annotations
function calculateTotal(price: number, tax: number): number {
return price * (1 + tax);
}

// React component Props types
interface ButtonProps {
children: React.ReactNode;
variant: 'primary' | 'secondary';
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
}

const Button: React.FC<ButtonProps> = ({ children, variant, onClick }) => {
return (
<button
className={`btn-${variant}`}
onClick={onClick}
>
{children}
</button>
);
};

Complex Type Applications in TanStack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// TanStack Query type definitions
interface UseUserQueryOptions {
userId: string;
enabled?: boolean;
staleTime?: number;
}

const useUserQuery = ({ userId, enabled = true, staleTime = 5000 }: UseUserQueryOptions) => {
return useQuery({
queryKey: ['user', userId],
queryFn: (): Promise<User> => fetchUser(userId),
enabled,
staleTime,
});
};

// TanStack Table column definitions
const columns: ColumnDef<User>[] = [
{
accessorKey: 'name',
header: 'Name',
cell: ({ row }: { row: Row<User> }) => row.getValue('name'),
},
];

Semicolon ; - Elegant Statement Termination

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Recommend always using semicolons
const name = "React";
const version = "18.0";

// Avoid ASI (Automatic Semicolon Insertion) issues
const result = calculate()
;[1, 2, 3].forEach(console.log); // Without semicolon will cause errors

// React Hook calls
useEffect(() => {
fetchData();
}, []);

// TanStack Query configuration
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000,
},
},
});

Bracket Family - Structure and Logic

Parentheses () - Container for Functions and Expressions

Function Calls and Definitions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Function calls
console.log("Hello World");
Array.from([1, 2, 3]);

// React function components
const Header = (props: HeaderProps) => {
return <h1>{props.title}</h1>;
};

// Higher-order components
const withAuth = (WrappedComponent: React.ComponentType) => {
return (props: any) => {
const { isAuthenticated } = useAuth();
return isAuthenticated ? <WrappedComponent {...props} /> : <Login />;
};
};

IIFE (Immediately Invoked Function Expression)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Create private scope
const module = (() => {
let privateVar = 0;
return {
increment: () => ++privateVar,
getCount: () => privateVar,
};
})();

// Conditional rendering in React
const ConditionalComponent = () => (
<div>
{(() => {
if (loading) return <LoadingSpinner />;
if (error) return <ErrorMessage error={error} />;
return <DataList data={data} />;
})()}
</div>
);

Square Brackets [] - Arrays and Dynamic Access

Array Literals

1
2
3
4
5
6
7
8
9
10
11
const frameworks = ['React', 'Vue', 'Angular'];
const numbers = [1, 2, 3, 4, 5];

// List rendering in React
const TodoList = ({ todos }: { todos: Todo[] }) => (
<ul>
{todos.map((todo, index) => (
<li key={todo.id || index}>{todo.text}</li>
))}
</ul>
);

Dynamic Property Access

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Dynamic property names
const property = 'userName';
const value = user[property];

// React form handling
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
setFormData(prev => ({
...prev,
[name]: value // Computed property name
}));
};

// Dynamic query keys in TanStack Query
const getDynamicQuery = (filters: Record<string, any>) => {
const queryKey = ['data', ...Object.entries(filters).map(([key, value]) => `${key}:${value}`)];
return useQuery({
queryKey,
queryFn: () => fetchData(filters),
});
};

Index Signatures and Mapped Types in TypeScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Index signatures
interface StringDictionary {
[key: string]: string;
}

// Mapped types
type Partial<T> = {
[P in keyof T]?: T[P];
};

type Required<T> = {
[P in keyof T]-?: T[P];
};

// Partial updates of React Props
interface UserFormProps {
user: User;
onUpdate: (updates: Partial<User>) => void;
}

Curly Braces {} - Objects and Code Blocks

Object Literals and Destructuring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Object literals
const apiConfig = {
baseUrl: 'https://api.example.com',
timeout: 5000,
headers: {
'Content-Type': 'application/json',
},
};

// Destructuring assignment
const { baseUrl, timeout, headers } = apiConfig;
const { data, error, isLoading } = useQuery();

// Nested destructuring
const {
user: { name, email },
preferences: { theme }
} = userProfile;

Expressions in JSX

1
2
3
4
5
6
7
8
9
10
11
12
const UserCard = ({ user, showEmail = false }: UserCardProps) => (
<div className="user-card">
<h3>{user.name}</h3>
{showEmail && <p>{user.email}</p>}
<div style={{
backgroundColor: user.isActive ? 'green' : 'gray',
padding: '10px'
}}>
Status: {user.isActive ? 'Active' : 'Inactive'}
</div>
</div>
);

Applications in TanStack Router

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Route configuration
const routeTree = createRootRoute({
component: () => (
<div>
<nav>{/* Navigation component */}</nav>
<main>
<Outlet />
</main>
</div>
),
});

// Dynamic route parameters
const userRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/users/$userId',
component: ({ params }: { params: { userId: string } }) => {
const { data: user } = useQuery({
queryKey: ['user', params.userId],
queryFn: () => fetchUser(params.userId),
});

return user ? <UserProfile user={user} /> : <div>Loading...</div>;
},
});

Advanced Operators and Type Symbols

Question Mark ? - The Power of Optional

Optional Properties and Parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Optional properties in interfaces
interface User {
id: string;
name: string;
email?: string; // Optional
avatar?: string; // Optional
}

// Optional function parameters
function createUser(name: string, email?: string): User {
return {
id: generateId(),
name,
...(email && { email }),
};
}

// Optional Props in React components
interface ButtonProps {
children: React.ReactNode;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}

const Button: React.FC<ButtonProps> = ({
children,
variant = 'primary',
disabled = false
}) => (
<button
className={`btn-${variant}`}
disabled={disabled}
>
{children}
</button>
);

Optional Chaining Operator ?.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Safe property access
const userEmail = user?.profile?.email;
const firstHobby = user?.hobbies?.[0];

// Optional method calls
user?.updateProfile?.({ name: 'New Name' });

// Safe rendering in React
const UserProfile = ({ user }: { user?: User }) => (
<div>
<h1>{user?.name || 'Guest'}</h1>
<p>{user?.email || 'No email provided'}</p>
{user?.avatar && <img src={user.avatar} alt="Avatar" />}
</div>
);

// Safe data access in TanStack Query
const UserDashboard = () => {
const { data: user } = useQuery({
queryKey: ['currentUser'],
queryFn: fetchCurrentUser,
});

return (
<div>
<h2>Welcome, {user?.name}!</h2>
<div>Points: {user?.gameStats?.points ?? 0}</div>
</div>
);
};

Ternary Operator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Basic conditional rendering
const status = isOnline ? 'Online' : 'Offline';

// Conditional rendering in React
const LoginButton = ({ isAuthenticated, onLogin, onLogout }: Props) => (
<button onClick={isAuthenticated ? onLogout : onLogin}>
{isAuthenticated ? 'Logout' : 'Login'}
</button>
);

// Nested ternary operators (use with caution)
const getStatusColor = (status: string) =>
status === 'success' ? 'green' :
status === 'error' ? 'red' :
status === 'warning' ? 'orange' : 'gray';

// TanStack Query state handling
const DataComponent = () => {
const { data, isLoading, error } = useQuery({
queryKey: ['data'],
queryFn: fetchData,
});

return (
<div>
{isLoading ? (
<LoadingSpinner />
) : error ? (
<ErrorMessage error={error} />
) : (
<DataList data={data} />
)}
</div>
);
};

Exclamation Mark ! - Assertion and Negation

Logical NOT Operator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const isNotActive = !user.isActive;
const isEmpty = !items.length;

// Conditional logic in React
const TodoItem = ({ todo, onToggle }: TodoItemProps) => (
<div className={!todo.completed ? 'pending' : 'completed'}>
<input
type="checkbox"
checked={!todo.completed}
onChange={() => onToggle(todo.id)}
/>
{todo.text}
</div>
);

TypeScript Non-null Assertion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Non-null assertion operator (use with caution)
const element = document.getElementById('root')!;
const user = getCurrentUser()!;

// Common usage with React Refs
const MyComponent = () => {
const inputRef = useRef<HTMLInputElement>(null);

const focusInput = () => {
inputRef.current!.focus(); // Ensuring current is not null
};

return <input ref={inputRef} />;
};

// Application in array methods
const users = getUsers();
const firstActiveUser = users.find(u => u.isActive)!; // Ensuring active user exists

Pipe | - The Wisdom of Union

TypeScript Union Types

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Basic union types
type Status = 'loading' | 'success' | 'error';
type ID = string | number;

// Union types for React component Props
interface ButtonProps {
variant: 'primary' | 'secondary' | 'danger';
size: 'small' | 'medium' | 'large';
children: React.ReactNode;
}

// Complex union types
type ApiResponse<T> =
| { status: 'success'; data: T }
| { status: 'error'; error: string }
| { status: 'loading' };

// Function handling union types
const handleApiResponse = <T>(response: ApiResponse<T>) => {
switch (response.status) {
case 'success':
return response.data; // TypeScript knows there's data here
case 'error':
throw new Error(response.error); // TypeScript knows there's error here
case 'loading':
return null;
}
};

Union Type Applications in TanStack Query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Union types for query status
type QueryStatus = 'idle' | 'loading' | 'error' | 'success';

// Union for multiple data sources
type DataSource =
| { type: 'api'; url: string }
| { type: 'cache'; key: string }
| { type: 'static'; data: any[] };

const useDataQuery = (source: DataSource) => {
return useQuery({
queryKey: ['data', source.type, source.type === 'api' ? source.url : source.type === 'cache' ? source.key : 'static'],
queryFn: () => {
switch (source.type) {
case 'api':
return fetch(source.url).then(r => r.json());
case 'cache':
return getCachedData(source.key);
case 'static':
return Promise.resolve(source.data);
}
},
});
};

Ampersand & - The Power of Intersection

TypeScript Intersection Types

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Basic intersection types
type User = { name: string; email: string };
type Admin = { permissions: string[] };
type AdminUser = User & Admin;

const adminUser: AdminUser = {
name: 'Alice',
email: 'alice@example.com',
permissions: ['read', 'write', 'delete']
};

// Combining React component Props
type BaseProps = {
className?: string;
children?: React.ReactNode;
};

type ButtonProps = BaseProps & {
onClick: () => void;
variant: 'primary' | 'secondary';
};

type LinkProps = BaseProps & {
href: string;
target?: '_blank' | '_self';
};

// Type composition for higher-order components
const withLoading = <P extends object>(Component: React.ComponentType<P>) => {
return (props: P & { isLoading: boolean }) => {
if (props.isLoading) {
return <div>Loading...</div>;
}
return <Component {...props} />;
};
};

Arrow => - Modern Function Syntax

Basic Arrow Functions

1
2
3
4
5
6
7
8
9
10
// Simple arrow functions
const add = (a: number, b: number) => a + b;
const greet = (name: string) => `Hello, ${name}!`;

// Arrow functions with type annotations
const processUser = (user: User): ProcessedUser => ({
...user,
displayName: user.name.toUpperCase(),
isVip: user.points > 1000,
});

Arrow Functions in React

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Function components
const Welcome: React.FC<{ name: string }> = ({ name }) => (
<h1>Welcome, {name}!</h1>
);

// Event handlers
const TodoApp = () => {
const [todos, setTodos] = useState<Todo[]>([]);

const addTodo = (text: string) => {
setTodos(prev => [...prev, { id: Date.now(), text, completed: false }]);
};

const toggleTodo = (id: number) => {
setTodos(prev => prev.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};

return (
<div>
<input
onKeyPress={(e) => {
if (e.key === 'Enter') {
addTodo((e.target as HTMLInputElement).value);
}
}}
/>
{todos.map(todo => (
<div key={todo.id} onClick={() => toggleTodo(todo.id)}>
{todo.text}
</div>
))}
</div>
);
};

Applications in TanStack Query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Query functions
const useUsers = () => useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(res => res.json()),
select: (data) => data.filter((user: User) => user.isActive), // Data transformation
});

// Mutation callbacks
const useCreateUser = () => useMutation({
mutationFn: (userData: CreateUserData) =>
fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData),
}).then(res => res.json()),
onSuccess: (newUser) => {
// Success callback
toast.success(`User ${newUser.name} created successfully!`);
},
onError: (error) => {
// Error callback
console.error('Failed to create user:', error);
},
});

Modern JavaScript TypeScript Advanced Symbols

Spread Operator ... - Expand and Collect

Array Operations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Array spreading
const numbers = [1, 2, 3];
const moreNumbers = [0, ...numbers, 4, 5];

// State updates in React
const TodoList = () => {
const [todos, setTodos] = useState<Todo[]>([]);

const addTodo = (newTodo: Todo) => {
setTodos(prev => [...prev, newTodo]);
};

const removeTodo = (id: string) => {
setTodos(prev => prev.filter(todo => todo.id !== id));
};
};

Object Operations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Object spreading and merging
const baseUser = { name: 'Alice', age: 25 };
const userWithEmail = { ...baseUser, email: 'alice@example.com' };

// Passing React Props
const UserCard = (props: UserCardProps) => (
<div {...props.divProps} className={`user-card ${props.divProps?.className || ''}`}>
<UserAvatar {...props.avatarProps} />
<UserInfo {...props.userProps} />
</div>
);

// Merging TanStack Query options
const createQueryOptions = <T>(
baseOptions: UseQueryOptions<T>,
customOptions: Partial<UseQueryOptions<T>> = {}
) => ({
...baseOptions,
...customOptions,
queryKey: [...baseOptions.queryKey, ...customOptions.queryKey || []],
});

Function Parameter Collection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Rest parameters
const logMessages = (...messages: string[]) => {
messages.forEach(msg => console.log(msg));
};

// Flexible parameters for React components
interface FlexibleButtonProps {
children: React.ReactNode;
onClick: () => void;
}

const FlexibleButton = ({ children, onClick, ...restProps }:
FlexibleButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>
) => (
<button onClick={onClick} {...restProps}>
{children}
</button>
);

Nullish Coalescing ?? and Logical Assignment

Nullish Coalescing Operator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Difference from ||
const port = process.env.PORT ?? 3000; // Only use default for null/undefined
const title = user.title ?? 'Untitled'; // Empty string won't be replaced

// Default value handling in React
const UserProfile = ({ user }: { user?: User }) => (
<div>
<h1>{user?.name ?? 'Anonymous'}</h1>
<p>Age: {user?.age ?? 'Not specified'}</p>
</div>
);

// Default data in TanStack Query
const useUserProfile = (userId: string) => {
return useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
placeholderData: (previousData) => previousData ?? getDefaultUser(),
});
};

Logical Assignment Operators

1
2
3
4
5
6
7
8
9
10
11
// ??= Nullish assignment
let config: AppConfig = getConfig();
config.theme ??= 'light'; // Only assign if null/undefined

// ||= Logical OR assignment
let cache: Record<string, any> = {};
cache.users ||= []; // Assign if falsy

// &&= Logical AND assignment
let settings: Settings = getUserSettings();
settings.notifications &&= validateNotificationSettings(settings.notifications);

Special Symbols and Modern Syntax

Template Literal Tags

Applications in styled-components

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import styled, { css } from 'styled-components';

// Basic styled component
const Button = styled.button`
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;

${props => props.primary && css`
background-color: blue;
color: white;
`}

${props => props.size === 'large' && css`
padding: 15px 30px;
font-size: 18px;
`}
`;

// Dynamic styles
const Container = styled.div<{ width: number; height: number }>`
width: ${props => props.width}px;
height: ${props => props.height}px;
background: linear-gradient(45deg,
${props => props.theme.primary},
${props => props.theme.secondary}
);
`;

GraphQL Query Templates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { gql } from '@apollo/client';

// GraphQL queries
const GET_USER_PROFILE = gql`
query GetUserProfile($userId: ID!) {
user(id: $userId) {
id
name
email
posts {
id
title
createdAt
}
}
}
`;

// Complex queries with variables
const SEARCH_USERS = gql`
query SearchUsers($filters: UserFilters!, $pagination: PaginationInput!) {
searchUsers(filters: $filters, pagination: $pagination) {
users {
...UserFragment
}
totalCount
hasNextPage
}
}

fragment UserFragment on User {
id
name
email
avatar
isActive
}
`;

Private Fields #

Private Members in Classes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class UserManager {
#users: User[] = [];
#currentUser: User | null = null;

// Private methods
#validateUser(user: User): boolean {
return user.name.length > 0 && user.email.includes('@');
}

// Public interface
addUser(user: User): boolean {
if (this.#validateUser(user)) {
this.#users.push(user);
return true;
}
return false;
}

getCurrentUser(): User | null {
return this.#currentUser;
}
}

// Application in React Class Components (less common)
class DataLoader extends React.Component {
#cache = new Map();
#loadingPromises = new Map();

#loadData = async (key: string) => {
if (this.#cache.has(key)) {
return this.#cache.get(key);
}

if (this.#loadingPromises.has(key)) {
return this.#loadingPromises.get(key);
}

const promise = fetch(`/api/data/${key}`).then(r => r.json());
this.#loadingPromises.set(key, promise);

try {
const data = await promise;
this.#cache.set(key, data);
return data;
} finally {
this.#loadingPromises.delete(key);
}
};
}

Comprehensive Applications in Real Projects

React TanStack Query Complete Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// Type definitions
interface User {
id: string;
name: string;
email: string;
avatar?: string;
isActive: boolean;
preferences: {
theme: 'light' | 'dark';
notifications: boolean;
};
}

interface UserListProps {
filters?: {
active?: boolean;
search?: string;
};
onUserSelect?: (user: User) => void;
}

// Custom Hook
const useUsers = ({ filters }: { filters?: UserListProps['filters'] } = {}) => {
return useQuery({
queryKey: ['users', filters],
queryFn: async (): Promise<User[]> => {
const params = new URLSearchParams();
if (filters?.active !== undefined) {
params.set('active', filters.active.toString());
}
if (filters?.search) {
params.set('search', filters.search);
}

const response = await fetch(`/api/users?${params}`);
if (!response.ok) {
throw new Error('Failed to fetch users');
}
return response.json();
},
staleTime: 5 * 60 * 1000, // 5 minutes
enabled: true,
});
};

// User update mutation
const useUpdateUser = () => {
const queryClient = useQueryClient();

return useMutation({
mutationFn: async ({ id, updates }: { id: string; updates: Partial<User> }): Promise<User> => {
const response = await fetch(`/api/users/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(updates),
});

if (!response.ok) {
throw new Error('Failed to update user');
}

return response.json();
},
onSuccess: (updatedUser) => {
// Update user data in cache
queryClient.setQueryData(
['users'],
(oldData: User[] | undefined) =>
oldData?.map(user =>
user.id === updatedUser.id ? updatedUser : user
) ?? []
);

// Also update individual user cache
queryClient.setQueryData(['user', updatedUser.id], updatedUser);
},
onError: (error) => {
console.error('Update failed:', error);
},
});
};

// Main component
const UserList: React.FC<UserListProps> = ({ filters, onUserSelect }) => {
const [searchTerm, setSearchTerm] = useState(filters?.search ?? '');
const [showActiveOnly, setShowActiveOnly] = useState(filters?.active ?? false);

// Debounced search
const debouncedSearch = useMemo(
() => debounce((term: string) => {
// Trigger search logic
}, 300),
[]
);

const queryFilters = useMemo(() => ({
active: showActiveOnly || undefined,
search: searchTerm || undefined,
}), [showActiveOnly, searchTerm]);

const { data: users = [], isLoading, error, refetch } = useUsers({ filters: queryFilters });
const updateUserMutation = useUpdateUser();

const handleUserToggle = useCallback((user: User) => {
updateUserMutation.mutate({
id: user.id,
updates: { isActive: !user.isActive },
});
}, [updateUserMutation]);

const handleSearchChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setSearchTerm(value);
debouncedSearch(value);
}, [debouncedSearch]);

if (isLoading) {
return <div className="loading">Loading users...</div>;
}

if (error) {
return (
<div className="error">
<p>Failed to load users: {error.message}</p>
<button onClick={() => refetch()}>Retry</button>
</div>
);
}

return (
<div className="user-list">
<div className="filters">
<input
type="text"
placeholder="Search users..."
value={searchTerm}
onChange={handleSearchChange}
/>
<label>
<input
type="checkbox"
checked={showActiveOnly}
onChange={(e) => setShowActiveOnly(e.target.checked)}
/>
Show active only
</label>
</div>

<div className="users">
{users.length === 0 ? (
<p>No users found.</p>
) : (
users.map((user) => (
<UserCard
key={user.id}
user={user}
onClick={() => onUserSelect?.(user)}
onToggleActive={() => handleUserToggle(user)}
isUpdating={updateUserMutation.isLoading}
/>
))
)}
</div>
</div>
);
};

// User card component
interface UserCardProps {
user: User;
onClick?: () => void;
onToggleActive?: () => void;
isUpdating?: boolean;
}

const UserCard: React.FC<UserCardProps> = memo(({
user,
onClick,
onToggleActive,
isUpdating = false
}) => (
<div
className={`user-card ${user.isActive ? 'active' : 'inactive'}`}
onClick={onClick}
>
<div className="user-info">
{user.avatar ? (
<img src={user.avatar} alt={`${user.name} avatar`} className="avatar" />
) : (
<div className="avatar-placeholder">
{user.name.charAt(0).toUpperCase()}
</div>
)}

<div className="details">
<h3>{user.name}</h3>
<p>{user.email}</p>
<div className="preferences">
Theme: {user.preferences.theme} |
Notifications: {user.preferences.notifications ? 'On' : 'Off'}
</div>
</div>
</div>

<button
onClick={(e) => {
e.stopPropagation();
onToggleActive?.();
}}
disabled={isUpdating}
className={`toggle-button ${user.isActive ? 'deactivate' : 'activate'}`}
>
{isUpdating ? '...' : (user.isActive ? 'Deactivate' : 'Activate')}
</button>
</div>
));

Best Practices Summary

Code Style Recommendations

  1. Consistency Principle

    • Maintain consistent quote usage throughout the project
    • Uniform semicolon usage (recommended to use)
    • Maintain consistent indentation and line breaks
  2. Readability First

    • Consider breaking complex ternary operators into if-else
    • Use parentheses appropriately to clarify operator precedence
    • Break long method chains with appropriate line breaks
  3. Type Safety

    • Prioritize using TypeScript’s strict mode
    • Use non-null assertion ! with caution
    • Utilize union and intersection types to improve type precision

Performance Considerations

  1. Object and Array Operations

    • Consider immutable libraries for large datasets
    • Avoid creating new objects in render functions
    • Use useMemo and useCallback judiciously
  2. Query Optimization

    • Set appropriate cache times for TanStack Query
    • Use hierarchical structure for query keys
    • Avoid unnecessary duplicate requests

Error Handling

  1. Defensive Programming

    • Use optional chaining to avoid null value errors
    • Provide reasonable default values
    • Handle async operation errors promptly
  2. User Experience

    • Provide loading state indicators
    • Friendly error messages
    • Support retry mechanisms

Conclusion

Punctuation symbols in TypeScript/JavaScript are not just syntax rules, but important tools for expressing complex logic and building modern applications. Mastering the usage of these symbols, especially their applications in React and TanStack ecosystem, helps us:

  1. Write safer code - Avoid runtime errors through type systems and optional chaining
  2. Improve development efficiency - Utilize modern syntax sugar and toolchains
  3. Build maintainable applications - Clear type definitions and component structures
  4. Optimize user experience - Through state management and data fetching optimization

Remember, tools themselves are not the goal; what matters is understanding when and how to correctly use these tools to solve real problems. In actual development, always focus on code readability, maintainability, and performance, choosing the most appropriate syntax and patterns for the current scenario.


This article covers the usage of major punctuation symbols in TypeScript/JavaScript, from basic syntax to advanced applications in modern frameworks. I hope this guide helps you better understand and utilize these powerful language features.