Several stack technology sharing front end: TS, see where you escape~

Data stack dtinsight 2021-08-09 17:27:32
stack technology sharing end ts

The number stack is — One stop big data development platform , We are github and gitee There's an interesting open source project on :FlinkX,FlinkX It's based on Flink Batch flow unified data synchronization tool , It can collect static data , It can also collect real-time changing data , It's global 、 isomerism 、 Batch stream integrated data synchronization engine . If you like, please give us some star!star!star!

github Open source project :

gitee Open source project :

If you are interested , Welcome to our communication community :30537511( Nail group )

Write it at the front

The difficulty of this paper is lower than middle , Most of the points involved are how to reasonably apply in the project TS, A small part will involve some principles , It has a wide audience , Yes no TS The foundation is safe to eat

After reading this article , You may get :

1、 If you are not familiar with TS, This article can help you complete TS The application part of learning , With so many Demo Example to guide the business application .

2、 If you are familiar with TS, This article can be used as a review article , Take you back to the knowledge , I hope it can arouse your new discovery and thinking at some point .

3、 Aim at class Component's IState and IProps, analogy Hook Part of the component writing and thinking .

TIPS: Super easy to use online TS Editor ( Many configuration items can be manually configured )

Portal :

What is? TS

No obscure concepts , Generally speaking TypeScript Namely JavaScript Superset , It has optional types , And can be compiled as pure JavaScript function .( The author has been putting TypeScript regard as JavaScript Of Lint)

So here comes the question , Why? TS It has to be designed to be static ? Or to put it another way , Why do we need to ask JavaScript Add type specification ?

Classic Q & a session —— Because it can solve some JS Unresolved pain points :1、JS It's a dynamic type of language , It also means that we don't know the type of the variable before instantiation , But use TS Classic low-level errors can be avoided before running .

example :Uncaught TypeError:'xxx' is not a function️ Mistakes in the level of allusion :

JS this is it , It's only when there's an error at runtime that you tell me there's an error , But when TS After the intervention :



good heavens ! Throw the problem directly in the editor phase ,nice!

2、 Lazy people revel ! Standard and convenient , It's not easy to make mistakes , about VS Code, The most it can do is to indicate whether it has this property , But it doesn't exactly indicate what type this property is , but TS It can be inferred by type / Inverse derivation ( To speak in vain : If you don't explicitly write the type , Type inference is used to infer the type you are using ), Thus the code completion is optimized perfectly :



1) first Q&A—— reflection : put questions to : So we can also think of in business development TS What has been solved JS My pain point ? answer , summary , Add :

  • Type restrictions on function parameters ;
  • Type restrictions on arrays and objects , Avoid definition errors For example, when data deconstruction is complex or more , There may be an array definition error a = { }, if (a.length){ // xxxxx }
  • let functionA = 'jiawen' // actually let functionA: string = 'jiawen'

3、 Make our application code easier to read and maintain , If the definition is perfect , The function of parameters can be understood by types . I believe that through the above simple bug-demo, All of you have said that TS There is a preliminary recognition The following chapters will formally introduce how to make good use of TS.

How to use it? TS

 How to use... In business TS/ How to make good use of it TS? This problem is actually related to " How to make good use of one in business API " It's the same . The first thing to know is what this thing is doing , What are the parameters , What are the rules , What extensions are acceptable ...... wait . In short , Roll it ! What extensions ...... wait . In short , Roll it !



1、TS Common types are summarized

Through the analysis of the common TS A comprehensive conclusion made by mistake , hope Demos It will be good for you

1) Metalanguage (primitives) And string number boolean

The reason why I take the basic types apart is : Whether it's in Chinese or English ,primitives/ Metalanguage / Tuples These nouns appear frequently , My understanding of vernacular : I hope that when type constraints are defined , Using literal quantities instead of built-in object types , Official documents :

let a: string = 'jiawen';let flag: boolean = false;let num: number = 150interface IState: { flag: boolean; name: string; num: number;}

2) Tuples

// Tuple type represents an array of known number and type of elements , The types of elements do not have to be the same , But the type of the corresponding location needs to be the same .
let x: [string, number];
x = ['jiawen', 18]; // ok
x = [18, 'jiawen']; // Erro
console.log(x[0]); // jiawen

3)undefined null

let special: string = undefined
// It is worth mentioning that undefined/null Is a subclass of all basic types ,
// So they can be arbitrarily assigned to other defined types , This is why the above code does not report an error 

4)object and { }

// object It means conventional Javascript object type , Non basic data types
const offDuty = (value: object) => {
console.log("value is ", value);
offDuty({ prop: 0}) // ok
offDuty(null) offDuty(undefined) // Error
offDuty(18) offDuty('offDuty') offDuty(false) // Error
// {} It means Not null / Not undefined Any type of
const offDuty = (value: {}) => {
console.log("value is ", value);
offDuty({ prop: 0}) // ok
offDuty(null) offDuty(undefined) // Error
offDuty(18) offDuty('offDuty') offDuty(false) // ok
offDuty({ toString(){ return 333 } }) // ok
// {} and Object Almost unanimously , The difference is that Object Would be right Object Built in toString/hasOwnPreperty check
const offDuty = (value: Object) => {
console.log("value is ", value);
offDuty({ prop: 0}) // ok
offDuty(null) offDuty(undefined) // Error
offDuty(18) offDuty('offDuty') offDuty(false) // ok
offDuty({ toString(){ return 333 } }) // Error
If you need an object type , But there is no requirement for attributes , It is recommended to use object
{} and Object The scope of the expression is too large , It is recommended not to use 

5)object of params

// We usually use point object function in business ( Specify the parameter object type )
const offDuty = (value: { x: number; y: string }) => {
console.log("x is ", value.x);
console.log("y is ", value.y);
// Business is bound to involve " Optional attribute "; Let's give a brief introduction to the convenient “ Optional attribute ”
const offDuty = (value: { x: number; y?: string }) => {
console.log(" Required attributes x ", value.x);
console.log(" Optional attribute y ", value.y);
console.log(" Optional attribute y Methods ", value.y.toLocaleLowerCase());
offDuty({ x: 123, y: 'jiawen' })
offDuty({ x: 123 })
// put questions to : Is there a problem with the above code ?
answer :
// offDuty({ x: 123 }) Will cause the result to report an error value.y.toLocaleLowerCase()
// Cannot read property 'toLocaleLowerCase' of undefined
programme 1: Manual type check
const offDuty = (value: { x: number; y?: string }) => {
if (value.y !== undefined) {
console.log(" It may not exist ", value.y.toUpperCase());
programme 2: Use optional properties ( recommend )
const offDuty = (value: { x: number; y?: string }) => {
console.log(" It may not exist ", value.y?.toLocaleLowerCase());

6)unknown And any

// unknown Can represent any type of , But it also tells TS, Developers are also unsure of the type , You need to be careful when doing anything
let Jiaven: unknown
Jiaven.toFixed(1) // Error
if (typeof Jiaven=== 'number') {
Jiaven.toFixed(1) // OK
When we use any When it comes to type ,any Will escape the type check , also any A variable of type can perform any operation , No errors will be reported at compile time
anyscript === javascript
Be careful :any It increases the risk of runtime errors , Don't use... Until you have to ;
If you want to express 【 I don't know what kind of 】 Scene , Recommend priority unknown

7)union Joint type

union Also called union type , Consisting of two or more other types , Represents a value that can be any one , Between types ' | ' separate
type dayOff = string | number | boolean
Implicit derivation of union types can lead to errors , If you have any questions, please refer to the words code and tips —— 《TS Implicit derivation of 》
. It is worth noting that , When accessing non common properties , Will report a mistake , Accessing shared properties does not . The last most intuitive demo
function dayOff (value: string | number): number {
return value.length;
// number Does not have length, Will report a mistake , resolvent :typeof value === 'string'
function dayOff (value: string | number): number {
return value.toString();
// number and string All have toString(), No mistake. 


// never It's other types ( Include null and undefined) Subtypes of , Represents a value that never appears .
// that never What role does it play in actual development ? Here I copy the classic explanation of youyuxi as the first example
First example , When you have one union type:
interface Foo {
type: 'foo'
interface Bar {
type: 'bar'
type All = Foo | Bar
stay switch In the middle of judgment type,TS It can be narrowed (discriminated union):
function handleValue(val: All) {
switch (val.type) {
case 'foo':
// here val Narrowed to Foo
case 'bar':
// val Here it is. Bar
// val Here it is. never
const exhaustiveCheck: never = val
Pay attention to default Inside we narrow it down to never Of val Assign a value to an object that is explicitly declared as never The variable of .
If all logic is right , So here should be able to compile through . But if one day your colleagues change All The type of :
type All = Foo | Bar | Baz
But he forgot to be in handleValue It's added to the list for Baz Processing logic ,
At this time in default branch Inside val Will be narrowed to Baz, This makes it impossible to assign to never, Generated a compilation error .
So in this way , You can make sure handleValue Always exhausted (exhaust) All All Possible types of 
 The second usage The return value is never The function of can be the case that throws an exception
function error(message: string): never {
throw new Error(message);
Third usage The return value is never The function of can be the end point that cannot be executed
function loop(): never {
while (true) {}


interface IProps {
onOK: () => void
void and undefined The function is highly similar , but void Indicates that you don't care about the return value of the function or that the method has no return value 


 The author thinks ts Medium enum Is a very interesting enumeration type , The bottom of it is number The implementation of the
1. Normal enumeration
enum Color {
let c: Color = Color.Blue;
console.log(c); // 2
2. String Enum
enum Color {
Red = 'red',
Green = 'not red',
3. Heterogeneous enumeration / Sometimes it's called mixed enumeration
enum Color {
Red = 'red',
Num = 2,
< The first pit >
enum Color {
A, // 0
B, // 1
C = 20, // 20
D, // 21
E = 100, // 100
F, // 101
If initialization has partial assignment , Then the value of the subsequent member is the value of the previous member plus 1
< The second pit > This pit is an extension of the first pit , If you are not careful, you will be deceived !
const getValue = () => {
return 23
enum List {
A = getValue(),
B = 24, // Here you have to initialize the value , Otherwise, the compilation fails
console.log(List.A) // 23
console.log(List.B) // 24
console.log(List.C) // 25
If the value of an attribute is calculated , Then the member next to it must initialize the value .
Otherwise it will be Enum member must have initializer.

11) Generic

I understand generics very colloquially : Don't specify the specific type first , Get the specific type by passing in the parameter type We start from the following filter-demo Starting with , Explore why generics are necessary

The basic style of generics



function fun<T>(args: T): T {
return args

If you don't have contact with , Do you feel a little confused ? No problem ! We're going straight into business .

1. The initial demand : Filter arrays of numeric types
declare function filter(
array: number[],
fn: (item: unknown) => boolean
) : number[];
2. The product changed the demand : And filter some strings string[]
Speed , Then use the overloading of functions , Add a statement , It's stupid , But it's easy to understand
declare function filter(
array: string[],
fn: (item: unknown) => boolean
): string[];
declare function filter(
array: number[],
fn: (item: unknown) => boolean
): number[];
3. Here comes the product again ! And this time it's going to filter boolean[]、object[] ..........
At this time, if you still choose overload , It will greatly increase the workload , The code will also become more and more cumbersome , This is when generics come out ,
It's more like a method in terms of implementation , Define the type by your parameters , The transformation is as follows :
declare function filter<T>(
array: T[],
fn: (item: unknown) => boolean
): T[];

When we understand generics as a method implementation , Then we naturally associate with : Method has multiple parameters 、 The default value is , Generics can also .

type Foo<T, U = string> = { // multi-parameter 、 The default value is
foo: Array<T> // It can deliver
bar: U
type A = Foo<number> // type A = { foo: number[]; bar: string; }
type B = Foo<number, number> // type B = { foo: number[]; bar: number; }

Since it is “ function ”, There will be “ Limit ”, Here are some slightly more common constraints .

1. extends: Limit T It has to be at least one XXX The type of
type dayOff<T extends HTMLElement = HTMLElement> = {
where: T,
name: string
2. Readonly<T>: Construct an all properties as readonly, This means that the properties of the constructed type cannot be reassigned .
interface Eat {
food: string;
const todo: Readonly<Eat> = {
food: "meat beef milk",
}; = "no food"; // Cannot assign to 'title' because it is a read-only property.
3. Pick<T,K>: from T Choose some of them K attribute
interface Todo {
name: string;
job: string;
work: boolean;
type TodoPreview = Pick<Todo, "name" | "work">;
const todo: TodoPreview = {
name: "jiawen",
work: true,


4. Omit<T, K>: Combined with the T and K And ignore... In the object type K To construct a type .
interface Todo {
name: string;
job: string;
work: boolean;
type TodoPreview = Omit<Todo, "work">;
const todo: TodoPreview = {
name: "jiawen",
job: 'job',
5.Record: constraint Define the key type as Keys、 The value type is Values Object type of .
enum Num {
A = 10001,
B = 10002,
C = 10003
const NumMap: Record<Num, string> = {
[Num.A]: 'this is A',
[Num.B]: 'this is B'
// type "{ 10001: string; 10002: string; }" Missing attribute in "10003",
// But the type "Record<ErrorCodes, string>" The attribute is required in , So we can also go through Record To do a comprehensive examination
keyof Keyword can be used to get all the information of an object type key type
type User = {
id: string;
name: string;
type UserKeys = keyof User; // "id" | "name"
The transformation is as follows
type Record<K extends keyof any, T> = {
[P in K]: T;
At this time T by any;
 There are also some not commonly used , But it's easy to understand :
6. Extract<T, U> from T,U Extract the same type from
7. Partial<T> All properties are optional
type User = {
id?: string,
gender: 'male' | 'female'
type PartialUser = Partial<User> // { id?: string, gender?: 'male' | 'female'}
type Partial<T> = { [U in keyof T]?: T[U] }
8. Required<T> All attributes must be << === >> And Partial contrary
type User = {
id?: string,
sex: 'male' | 'female'
type RequiredUser = Required<User> // { readonly id: string, readonly gender: 'male' | 'female'}
function showUserProfile (user: RequiredUser) {
console.log( // At this time, there is no need to add ? 了
type Required<T> = { [U in keyof T]-?: T[U] }; -? : It's for getting rid of ?


TS Some things to know about

1、TS Of type and interface

1)interface( Interface ) Only object types can be declared , Support for statement merging ( Scalable ).

interface User { id: string}interface User { name: string}const user = {} as Userconsole.log(;console.log(;


2)type( Type the alias ) Declaration merge is not supported -- l type

type User = {
id: string,
if (true) {
type User = {
name: string,
const user = {} as User;
console.log( // type “User” Property does not exist on “id”.




3)type and interface Summary of similarities and differences :

a、 Generally speaking type More general , The right side can be any type , Including expression operations , And mapping ;

b、 Whatever is available interface To define the ,type Can also be ;

c、 There are also different ways to expand ,interface It can be used extends Keyword extension , Or for implements Implement an interface ;

d、 Can be used to describe an object or function ;

e、type You can declare basic type aliases 、 Joint type 、 A tuple type ,interface no way ;

f、️ But if you're developing a package , modular , Allow others to expand and use interface, If you need to define basic data types or type operations , Use type;

g、interface Can be defined many times , And will be treated as a merger statement , and type I won't support it ;

h、 Different ways to export ,interface Support both declaration and default export , and typetype Must declare before exporting ;r/>

2、TS Script mode and module mode of

Typescript There are two patterns , The logic of distinction is , The file content pack does not contain import perhaps export keyword .

1) Script mode (Script), One file corresponds to one html Of script label .

2) Module mode (Module), One file corresponds to one Typescript Module .

In script mode , All variable definitions , Type declarations are global , If multiple files define the same variable, an error will be reported , The same name interface Will merge ; In module mode , All variable definitions , Type declarations are valid within a module .

The two patterns are also different when writing type declarations , For example, in script mode, direct declare var GlobalStore You can write a declaration for the global object .

Example :

In script mode, directly declare var GlobalStore You can write a declaration for the global object . = "foo"; = "bar"; // Error
declare var GlobalStore: {
foo: string;


In module mode , To write a declaration for a global object, you need declare global = "foo"; = "bar";
declare global {
var GlobalStore: {
foo: string;
bar: string;
export {}; // export Keywords change the mode of the file 


3、TS The index signature of

Index signatures can be used to define properties within an object 、 The type of value , For example, define a React Components , allow Props You can pass it anywhere key by string,value by number Of props

interface Props {
[key: string]: number
<Component count={1} /> // OK
<Component count={true} /> // Error
<Component count={'1'} /> // Error


4、TS Type

Typescript Allows you to use types just as objects take property values

type User = {
userId: string
friendList: {
fristName: string
lastName: string
type UserIdType = User['userId'] // string
type FriendList = User['friendList'] // { fristName: string; lastName: string; }[]
type Friend = FriendList[number] // { fristName: string; lastName: string; }


In the example above , We use the ability to type in from User Several other types are calculated from the type .FriendList[number] there number Is the key word , Used to get the type of array subitems . You can also use literal numbers in tuples to get the type of array elements .

type group = [number, string]
type First = group[0] // number
type Second = group[1] // string


5、TS Assertion of

1) Type assertion is not a type conversion , It is not allowed to assert a type that does not exist in a union type .

function getLength(value: string | number): number {
if (value.length) {
return value.length;
} else {
return value.toString().length;
// The question is object of parmas It has been mentioned that , I won't repeat
After modification :
if ((<string>value).length) {
return (<string>value).length;
} else {
return something.toString().length;


 Two ways of writing assertions
1. < type > value : <string>value
2. perhaps value as string
Particular attention !!! It is not allowed to assert a type that does not exist in a union type
function toBoolean(something: string | number): boolean {
return <boolean>something;


2) Non null assertion

TypeScript It also has a special syntax , Used to remove... From a type null and undefined No explicit checking .

Writing after any expression is actually a type assertion , Indicates that the value is not null or undefined

function liveDangerously(x?: number | undefined | null) {
// Recommend writing


How to be in Hook Used in components TS


useState If the initial value is not null/undefined Words , It has the ability of type derivation , Infer the type... From the initial value passed in ; The initial value is null/undefined You need to pass the type definition to constrain . In general , We recommend the incoming type ( adopt useState The first generic parameter of ).

// here ts It can be inferred value And can be used for setValue Function call to constrain
const [value, setValue] = useState(0);
interface MyObject {
name: string;
age?: number;
// It needs to be delivered here MyObject To restrain value, setValue
// So we generally recommend the incoming type
const [value, setValue] = useState<MyObject>(null);


2)useEffect useLayoutEffect

no return value , No type passing and constraints

3)useMemo useCallback

  • useMemo No need to pass type , The type can be inferred from the return value of the function .
  • useCallback No need to pass type , The type can be inferred from the return value of the function .

But notice that the function's arguments need to define the type , Otherwise it would be inferred that any!

const value = 10;
const result = useMemo(() => value * 2, [value]); // Deduce result yes number type
const multiplier = 2;
// Deduce (value: number) => number
// Notice the function arguments value Need to define type
const multiply = useCallback((value: number) => value * multiplier, [multiplier]);



useRef You can infer the type when you pass a non null initial value , You can also define a type by passing in the first generic parameter , constraint ref.current The type of .

1. If the value is null
const MyInput = () => {
const inputRef = useRef<HTMLInputElement>(null); // Constraint here inputRef It's a html Elements
return <input ref={inputRef} />
2. If not for null
const myNumberRef = useRef(0); // Automatically infer myNumberRef.current yes number type
myNumberRef.current += 1;



useContext Generally according to the incoming Context We can infer the return value of . Generally, there is no need to display the pass type .

type Theme = 'light' | 'dark';// We are createContext Just passed on the type const ThemeContext = createContext<Theme>('dark');const App = () => ( <ThemeContext.Provider value="dark"> <MyComponent /> </ThemeContext.Provider>)const MyComponent = () => { // useContext according to ThemeContext Infer the type , There is no need to show the transmission const theme = useContext(ThemeContext); return <div>The theme is {theme}</div>


Some thoughts

In this paper, the author discusses TS Basic application and Hook Medium TS Did some thinking , But about TSC How to make TS Code conversion to JS The content of the code , This part is rather lengthy , Follow up can be a separate article (2) To explore . About TS The underlying implementation of generics , This part is more complicated , I still need precipitation , Welcome to leave a message or add in the article !!!

This article by the blog one article many sends the platform OpenWrite Release !
本文为[Data stack dtinsight]所创,转载请带上原文链接,感谢

  1. HTML + CSS + JavaScript to achieve cool Fireworks (cloud like particle text 3D opening)
  2. HTML + CSS + JavaScript realizes 520 advertising love tree (including music), which is necessary for programmers to express themselves
  3. Solve the problem of Web front-end deployment server (it can be deployed online without a server)
  4. HTML + CSS + JS make wedding countdown web page template (520 / Tanabata Valentine's Day / programmer advertisement)
  5. What else can driverless minibus do besides "Park connection"?
  6. Cloud native leads the era of all cloud development
  7. NRM mirror source management tool
  8. Bring it to you, flex Jiugong
  9. Lolstyle UI component development practice (II) -- button group component
  10. Deconstruction assignment in ES6
  11. Luo 2 peerless Tang clan was officially launched. The official gave a key point, and the broadcast time was implied
  12. 20初识前端HTML(1)
  13. 当新零售遇上 Serverless
  14. 20 initial knowledge of front-end HTML (1)
  15. When new retail meets serverless
  16. [golang] - go into go language lesson 5 type conversion
  17. [golang] - go into go language lesson 6 conditional expression
  18. HTML5(八)——SVG 之 path 详解
  19. HTML5 (8) -- detailed explanation of SVG path
  20. 需要开通VIP以后页面内容才能复制怎么办?控制台禁用javascript即可
  21. Web前端|CSS入门教程(超详细的CSS使用讲解,适合前端初学者)
  22. 实践积累 —— 用Vue3简单写一个单行横向滚动组件
  23. Serverless 全能选手,再下一城
  24. What if you need to open a VIP to copy the page content? Just disable JavaScript on the console
  25. Web front end | CSS introductory tutorial (super detailed CSS explanation, suitable for front-end beginners)
  26. Practice accumulation - write a single line horizontal scroll component simply with vue3
  27. Dili Reba is thin again. She looks elegant and high in a strapless hollow skirt, and her "palm waist" is beautiful to a new height
  28. Serverless all-round player, next city
  29. The difference between MySQL semi synchronous replication and lossless semi synchronous replication
  30. Vue表单设计器的终极解决方案
  31. The ultimate solution for Vue form designer
  32. Nginx从理论到实践超详细笔记
  33. Yu Shuxin's red backless swimsuit is split to the waist and tail, with a concave convex figure and excessive color matching, and his face is white to dazzling
  34. Nginx ultra detailed notes from theory to practice
  35. 【动画消消乐|CSS】086.炫酷水波浪Loading过渡动画
  36. typecho全站启用https
  37. CCTV has another popular employee. The off-site interpretation is very professional, and the appearance ability is no less than that of Wang Bingbing
  38. [animation Xiaole | CSS] 086. Cool water wave loading transition animation
  39. Enable HTTPS in Typecho
  40. 50天用JavaScript完成50个web项目,我学到了什么?
  41. 根据JavaScript中原生的XMLHttpRequest实现jQuery的Ajax
  42. What have I learned from completing 50 web projects with JavaScript in 50 days?
  43. "My neighbor doesn't grow up" has hit the whole network. There are countless horse music circles, and actor Zhou Xiaochuan has successfully made a circle
  44. 根据JavaScript中原生的XMLHttpRequest实现jQuery的Ajax
  45. Implement the Ajax of jQuery according to the native XMLHttpRequest in JavaScript
  46. Implement the Ajax of jQuery according to the native XMLHttpRequest in JavaScript
  47. 30 + women still wear less T-shirts and jeans. If they wear them like stars, they will lose weight
  48. 数栈技术分享前端篇:TS,看你哪里逃~
  49. Several stack technology sharing front end: TS, see where you escape~
  50. 舍弃Kong和Nginx,Apache APISIX 在趣链科技 BaaS 平台的落地实践
  51. Abandon the landing practice of Kong and nginx, Apache apisik on the baas platform of fun chain technology
  52. 浪迹天涯king教你用elementui做复杂的表格,去处理报表数据(合并表头,合并表体行和列)
  53. 前端HTML两万字图文大总结,快来看看你会多少!【️熬夜整理&建议收藏️】
  54. Wandering around the world king teaches you to use elementui to make complex tables and process report data (merge header, merge table body rows and columns)
  55. 路由刷新数据丢失 - vuex数据读取的问题
  56. Front end HTML 20000 word graphic summary, come and see how much you can【 Stay up late to sort out & suggestions]
  57. Route refresh data loss - vuex data reading problem
  58. Systemctl系统启动Nginx服务脚本
  59. Systemctl system startup nginx service script
  60. sleepless