Duong Tran

Duong Tran

1659038400

Cải Thiện Chất Lượng Mã Trong Typecript Với Các Tùy Chọn

Typecript là một ngôn ngữ lập trình được phát triển bởi Microsoft để mang lại sự bảo mật trong việc kiểm tra kiểu nghiêm ngặt và an toàn gõ, cho ngôn ngữ Javascript. Nó là một tập hợp siêu Javascript cũng được biên dịch sang Javascript. TypeScript cung cấp một số tùy chọn trình biên dịch thay đổi cách nó hoạt động. Các tùy chọn này có các mục đích sử dụng quan trọng khác nhau, như xóa nhận xét hoặc thêm URL cơ sở để phân giải tên mô-đun.

Trong bài viết này, chúng ta sẽ xem xét các tùy chọn để cải thiện chất lượng mã trong Typecript bằng cách thiết lập một số tùy chọn phù hợp.

Tệp tsconfig.json

Tệp tsconfig.jsonchứa tất cả các tùy chọn trình biên dịch. Sự hiện diện hiển thị và chỉ định sự hiện diện của gốc dự án Typecript. Có thể nhận tệp bằng cách gõ tsc --initlệnh trong thiết bị đầu cuối. Dưới đây là một số ví dụ về một số tùy chọn trình biên dịch

{
    "compilerOptions": {
        "module": "system",
        "noImplicitAny": true,
        "removeComments": true,
        "allowUnreachableCode": false,
        "strictNullChecks": true,
        "target": "es5", 
        "module": "commonjs", 
        "rootDir": ".",
        "outDir": "../dist/",
        "sourceMap": true 
    }
}

Trong bài viết này , chúng ta sẽ nói về việc cải thiện chất lượng mã với các tùy chọn noUnusedLocals,,, noUnusedParametersvà .noImplicitReturnsnoFallthroughCasesInSwitchstrictNullChecksnoImplicitAnynoImplicitThisstrictBindCallApply

noUnusedLocals

Với tùy chọn này được đặt thành true, trình biên dịch sẽ kiểm tra và tạo ra lỗi trên các biến cục bộ không sử dụng, theo cách tương tự như no-unused-varstrong ESLint . Tùy chọn trình biên dịch này nhằm mục đích loại bỏ và loại bỏ các biến không sử dụng trong Typecript. Hãy xem xét ví dụ dưới đây:

const numHandler = (input: number) => {
  let digits;
  return input;
};

Trong ví dụ trên, chúng ta đã định nghĩa một hàm được gọi numHandler, hàm này nhận một tham số là kiểu số. Tiếp theo, chúng tôi xác định một digitsbiến và trả về tham số đầu vào. Khi chúng tôi biên dịch đoạn mã trên, chúng tôi gặp lỗi bên dưới từ thiết bị đầu cuối:

error TS6133: 'digits' is declared but its value is never read

Lỗi này được tạo ra bởi vì chúng tôi đã khai báo digitsbiến mà không sử dụng nó. Bạn có thể loại bỏ lỗi này bằng cách sử dụng giá trị được khai báo ở đâu đó trong mã hoặc bằng cách đặt tùy chọn trong tệp tsconfig.json thành false.

noUnusedParameter

Tùy chọn trình biên dịch này hơi giống với noUnusedLocalstùy chọn. Sự khác biệt là trong khi noUnusedLocalstạo ra lỗi trên các biến cục bộ không sử dụng, noUnusedParametersẽ tạo ra lỗi khi các tham số hàm được khai báo nhưng không được sử dụng. Hãy xem xét ví dụ dưới đây:

const anExample = (input: string) => {
  const someStrings = 'The name is Isaac'
  return { true, someStrings };
};

Chúng tôi đã định nghĩa một hàm được gọi anExample, hàm này nhận một stringtham số kiểu. Tiếp theo, chúng tôi xác định một biến được gọi someStringsvà sau đó trả về một giá trị boolean và biến đã xác định. Khi chúng tôi biên dịch đoạn mã trên, chúng tôi gặp lỗi bên dưới từ thiết bị đầu cuối:

error TS6133: 'input' is declared but its value is never read

Điều này xảy ra vì chúng ta đã khai báo inputtham số trong hàm mà không sử dụng nó. Bạn có thể loại bỏ lỗi này bằng cách sử dụng tham số được khai báo trong thân hàm hoặc bằng cách đặt tùy chọn trong tsconfig.jsontệp thành false.

noImplicitReturns

Tùy chọn trình biên dịch này đảm bảo rằng bất kỳ hàm nào có khai báo trả về đều trả về một thứ gì đó. Tùy chọn này tạo ra lỗi khi đường dẫn mã trong một hàm không trả về giá trị. Hãy xem xét ví dụ dưới đây:

function add(input: number, output: number) {
  if (input + output > 0) {
    return input + output;
  }
}

Trong ví dụ trên, chúng ta đã định nghĩa một hàm có hai tham số kiểu số. Tiếp theo, chúng ta đặt một câu lệnh if, câu lệnh này sẽ kiểm tra xem tổng của cả hai tham số có lớn hơn 0 hay không và sau đó nó trả về tổng đó. Với tùy chọn trình biên dịch này được đặt thành true, trình biên dịch sẽ tạo ra lỗi loại bên dưới:

error TS7030: Not all code paths return a value.

Typecript phát hiện ở đây rằng không phải tất cả các đường dẫn mã đều trả về thứ gì đó. Không có returntuyên bố nào về thời điểm tổng các đối số không dương và điều này có thể đưa lỗi vào mã của chúng ta vì hàm trên sẽ trả về không xác định. Để giải quyết vấn đề này, hãy đảm bảo rằng tất cả các phần của mã trả về một cái gì đó. Hãy xem xét giải pháp cho đoạn mã trên dưới đây:

function add(input: number, output: number) {
  if (input + output > 0) {
    return input + output;
  }
  return
}

Bằng cách sử dụng từ khóa return, chúng tôi đảm bảo rằng tất cả các phần trong mã của chúng tôi đều trả về một thứ gì đó. Tùy chọn trình biên dịch đã giúp chúng tôi phát hiện tình huống thiếu có thể xảy ra và tránh lỗi.

Phát lại phiên nguồn mở

OpenReplay là một bộ mã nguồn mở, phát lại phiên cho phép bạn xem những gì người dùng làm trên ứng dụng web của bạn, giúp bạn khắc phục sự cố nhanh hơn. OpenReplay được tự lưu trữ để kiểm soát toàn bộ dữ liệu của bạn.

replayer.png

Bắt đầu tận hưởng trải nghiệm gỡ lỗi của bạn - bắt đầu sử dụng OpenReplay miễn phí .

noFallthroughCasesInSwitch

Khi được đặt thành true, tùy chọn trình biên dịch này tạo ra lỗi bất cứ khi nào chúng ta có switchcác câu lệnh chuyển từ nhánh này sang nhánh khác mà không có breakhoặc returntừ khóa. Hãy xem xét ví dụ dưới đây:

let name = 'Isaac';
  
switch (name) {
  case 'Isaac':
    console.log('Isaac is a developer');
  case 'John':
    console.log('John is my friend');
    break;           
}

Khi chúng tôi biên dịch mã ở trên, chúng tôi gặp lỗi bên dưới.

error TS7029: Fallthrough case in switch

Điều này xảy ra bởi vì có một breaktừ khóa bị bỏ qua trong nhánh của switchcâu lệnh đầu tiên. Đôi khi bạn có thể có những lý do hợp lệ để bỏ qua breaktừ khóa đã nói, nhưng đó thường là một lỗi. Một số giải pháp cho điều này là:

  • Đặt noFallthroughCasesInSwitch thành false trong tsconfig.jsontệp
  • Sử dụng // @ts-ignorelệnh để loại bỏ lỗi

strictNullChecks

Tùy chọn trình biên dịch này kiểm tra các trường hợp mà Typecript mong đợi một kiểu cụ thể (số, chuỗi, boolean) nhưng bị null hoặc không xác định khi được đặt thành true. Tùy chọn này giúp chúng tôi loại bỏ Uncaught TypeErrorlỗi. Hãy xem xét ví dụ bên dưới:

let title: string;
name = title;
console.log(name);

Khi chúng tôi biên dịch và chạy đoạn mã ở trên, chúng tôi gặp lỗi bên dưới:

error TS2454: Variable 'title' is used before being assigned

Giải pháp cho lỗi này là gán một giá trị cho biến trước khi sử dụng nó, như chúng ta thấy trong khối mã bên dưới:

let title: string = "Student"
name = title
console.log(name)

noImplicitAny

Mỗi biến trong Typecript đều có một kiểu; hoặc chúng tôi xác định loại hoặc Loại chỉ định cố gắng đoán nó. Hãy xem xét ví dụ dưới đây:

function value(a) {
  return;
}

Trong khối mã ở trên, chúng ta có một hàm với đối số là a; vì chúng tôi không xác định kiểu cho đối số đó, vì vậy, Typescript suy ra rằng đối số có một anykiểu. Với tùy chọn trình biên dịch này được đặt thành true, trình biên dịch sẽ tạo ra lỗi bên dưới:

error TS7006: Parameter 'a' implicitly has an 'any' type

Giải pháp cho điều này là đảm bảo rằng bạn xác định đúng kiểu cho mọi đối số.

noImplicitThis

Với tùy chọn trình biên dịch này được đặt thành true, Typescript sẽ phàn nàn bất cứ khi nào có trường hợp chúng tôi đang sử dụng thistừ khóa không đúng cách hoặc ở một nơi không rõ ràng nơi thisđề cập đến.

class Person {
  weight: number;
  height: number;
  
  constructor(weight: number, height: number) {
    this.weight = weight;
    this.height = height;
  }
  
  getBodyMassIndex() {
    return function () {
      return this.weight / (this.height * this.height);
    };
  }
}

Chúng tôi gặp lỗi bên dưới khi biên dịch mã ở trên do phạm vi trong Javascript. Điều này là do ngữ cảnh của thistừ khóa không bị ràng buộc với bất kỳ trường hợp nào của từ khóa Persontheo mặc định.

error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation

Giải pháp cho điều này là các hàm mũi tên. Điều này sẽ hoạt động vì các hàm mũi tên sử dụng ngữ cảnh thực thi của cha mẹ :

class Person {
  weight: number;
  height: number;
  
  constructor(weight: number, height: number) {
    this.weight = weight;
    this.height = height;
  }
  
  getBodyMassIndex() {
    return () => {
      return this.weight / (this.height * this.height);
    };
  }
}

strictBindCallApply

Tùy chọn trình biên dịch này đảm bảo rằng bạn đang sử dụng call()bind()các apply()hàm với các đối số phù hợp.

const numHandler = (a: number) ={
  console.log(`log ${a}!`);
}

numHandler.call(undefined, 'Isaac')

Khi chúng tôi chạy đoạn mã trên với tùy chọn trình biên dịch này được đặt thành true, chúng tôi gặp lỗi:

error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'

Để giải quyết vấn đề này, chúng ta cần chuyển đối số đúng và lỗi sẽ được giải quyết.

const numHandler = (a: number) ={
  console.log(`log ${a}!`)
}
    
numHandler.call(undefined, '25')

Sự kết luận

Trong bài viết này, chúng tôi đã xem xét một số tùy chọn trình biên dịch, các lỗi mà chúng tạo ra, cách giải quyết chúng và cách cải thiện chất lượng mã bằng cách sử dụng chúng. Nhiều tùy chọn trình biên dịch khác có thể giúp cải thiện chất lượng mã và bạn có thể xem chúng tại đây .

Nguồn: https://blog.openreplay.com/improving-code-quality-in-typescript-with-compiler-options

#typescript 

What is GEEK

Buddha Community

Cải Thiện Chất Lượng Mã Trong Typecript Với Các Tùy Chọn
Zachary Palmer

Zachary Palmer

1555901576

CSS Flexbox Tutorial | Build a Chat Application

Creating the conversation sidebar and main chat section

In this article we are going to focus on building a basic sidebar, and the main chat window inside our chat shell. See below.

Chat shell with a fixed width sidebar and expanded chat window

This is the second article in this series. You can check out the previous article for setting up the shell OR you can just check out the chat-shell branch from the following repository.

https://github.com/lyraddigital/flexbox-chat-app.git

Open up the chat.html file. You should have the following HTML.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Chat App</title>
    <link rel="stylesheet" type="text/css" media="screen" href="css/chat.css" />
</head>
<body>
    <div id="chat-container">
    </div>
</body>
</html>

Now inside of the chat-container div add the following HTML.

<div id="side-bar">
</div>
<div id="chat-window">
</div>

Now let’s also add the following CSS under the #chat-container selector in the chat.css file.

#side-bar {
    background: #0048AA;
    border-radius: 10px 0 0 10px;
}
#chat-window {
    background: #999;
    border-radius: 0 10px 10px 0;
}

Now reload the page. You should see the following:-

So what happened? Where is our sidebar and where is our chat window? I expected to see a blue side bar and a grey chat window, but it’s no where to be found. Well it’s all good. This is because we have no content inside of either element, so it can be 0 pixels wide.

Sizing Flex Items

So now that we know that our items are 0 pixels wide, let’s attempt to size them. We’ll attempt to try this first using explicit widths.

Add the following width property to the #side-bar rule, then reload the page.

width: 275px;

Hmm. Same result. It’s still a blank shell. Oh wait I have to make sure the height is 100% too. So we better do that too. Once again add the following property to the #side-bar rule, then reload the page.

height: 100%;

So now we have our sidebar that has grown to be exactly 275 pixels wide, and is 100% high. So that’s it. We’re done right? Wrong. Let me ask you a question. How big is the chat window? Let’s test that by adding some text to it. Try this yourself just add some text. You should see something similar to this.

So as you can see the chat window is only as big as the text that’s inside of it, and it is not next to the side bar. And this makes sense because up until now the chat shell is not a flex container, and just a regular block level element.

So let’s make our chat shell a flex container. Set the following display property for the #chat-window selector. Then reload the page.

display: flex;

So as you can see by the above illustration, we can see it’s now next to the side bar, and not below it. But as you can see currently it’s only as wide as the text that’s inside of it.

But we want it to take up the remaining space of the chat shell. Well we know how to do this, as we did it in the previous article. Set the flex-grow property to 1 on the #chat-window selector. Basically copy and paste the property below and reload the page.

flex-grow: 1;

So now we have the chat window taking up the remaining space of the chat shell. Next, let’s remove the background property, and also remove all text inside the chat-window div if any still exists. You should now see the result below.

But are we done? Technically yes, but before we move on, let’s improve things a little bit.

Understanding the default alignment

If you remember, before we had defined our chat shell to be a flex container, we had to make sure we set the height of the side bar to be 100%. Otherwise it was 0 pixels high, and as a result nothing was displayed. With that said, try removing the height property from the #side-bar selector and see what happens when you reload the page. Yes that’s right, it still works. The height of the sidebar is still 100% high.

So what happened here? Why do we no longer have to worry about setting the height to 100%? Well this is one of the cool things Flexbox gives you for free. By default every flex item will stretch vertically to fill in the entire height of the flex container. We can in fact change this behaviour, and we will see how this is done in a future article.

Setting the size of the side bar properly

So another feature of Flexbox is being able to set the size of a flex item by using the flex-basis property. The flex-basis property allows you to specify an initial size of a flex item, before any growing or shrinking takes place. We’ll understand more about this in an upcoming article.

For now I just want you to understand one important thing. And that is using width to specify the size of the sidebar is not a good idea. Let’s see why.

Say that potentially, if the screen is mobile we want the side bar to now appear across the top of the chat shell, acting like a top bar instead. We can do this by changing the direction flex items can flex inside a flex container. For example, add the following CSS to the #chat-container selector. Then reload the page.

flex-direction: column;

So as you can see we are back to a blank shell. So firstly let’s understand what we actually did here. By setting the flex-direction property to column, we changed the direction of how the flex items flex. By default flex items will flex from left to right. However when we set flex-direction to column, it changes this behaviour forcing flex items to flex from top to bottom instead. On top of this, when the direction of flex changes, the sizing and alignment of flex items changes as well.

When flexing from left to right, we get a height of 100% for free as already mentioned, and then we made sure the side bar was set to be 275 pixels wide, by setting the width property.

However now that we a flexing from top to bottom, the width of the flex item by default would be 100% wide, and you would need to specify the height instead. So try this. Add the following property to the #side-bar selector to set the height of the side bar. Then reload the page.

height: 275px;

Now we are seeing the side bar again, as we gave it a fixed height too. But we still have that fixed width. That’s not what we wanted. We want the side bar (ie our new top bar) here to now be 100% wide. Comment out the width for a moment and reload the page again.

So now we were able to move our side bar so it appears on top instead, acting like a top bar. Which as previously mentioned might be suited for mobile device widths. But to do this we had to swap the value of width to be the value of height. Wouldn’t it be great if this size was preserved regardless of which direction our items are flexing.

Try this, remove all widths and height properties from the #side-bar selector and write the following instead. Then reload the page.

flex-basis: 275px;

As you can see we get the same result. Now remove the flex-direction property from the #chat-container selector. Then once again reload the page.

Once again we are back to our final output. But now we also have the flexibility to easily change the side bar to be a top bar if we need to, by just changing the direction items can flow. Regardless of the direction of flex, the size of our side bar / top bar is preserved.

Conclusion

Ok so once again we didn’t build much, but we did cover a lot of concepts about Flexbox around sizing. 

#css #programming #webdev 

Duong Tran

Duong Tran

1659038400

Cải Thiện Chất Lượng Mã Trong Typecript Với Các Tùy Chọn

Typecript là một ngôn ngữ lập trình được phát triển bởi Microsoft để mang lại sự bảo mật trong việc kiểm tra kiểu nghiêm ngặt và an toàn gõ, cho ngôn ngữ Javascript. Nó là một tập hợp siêu Javascript cũng được biên dịch sang Javascript. TypeScript cung cấp một số tùy chọn trình biên dịch thay đổi cách nó hoạt động. Các tùy chọn này có các mục đích sử dụng quan trọng khác nhau, như xóa nhận xét hoặc thêm URL cơ sở để phân giải tên mô-đun.

Trong bài viết này, chúng ta sẽ xem xét các tùy chọn để cải thiện chất lượng mã trong Typecript bằng cách thiết lập một số tùy chọn phù hợp.

Tệp tsconfig.json

Tệp tsconfig.jsonchứa tất cả các tùy chọn trình biên dịch. Sự hiện diện hiển thị và chỉ định sự hiện diện của gốc dự án Typecript. Có thể nhận tệp bằng cách gõ tsc --initlệnh trong thiết bị đầu cuối. Dưới đây là một số ví dụ về một số tùy chọn trình biên dịch

{
    "compilerOptions": {
        "module": "system",
        "noImplicitAny": true,
        "removeComments": true,
        "allowUnreachableCode": false,
        "strictNullChecks": true,
        "target": "es5", 
        "module": "commonjs", 
        "rootDir": ".",
        "outDir": "../dist/",
        "sourceMap": true 
    }
}

Trong bài viết này , chúng ta sẽ nói về việc cải thiện chất lượng mã với các tùy chọn noUnusedLocals,,, noUnusedParametersvà .noImplicitReturnsnoFallthroughCasesInSwitchstrictNullChecksnoImplicitAnynoImplicitThisstrictBindCallApply

noUnusedLocals

Với tùy chọn này được đặt thành true, trình biên dịch sẽ kiểm tra và tạo ra lỗi trên các biến cục bộ không sử dụng, theo cách tương tự như no-unused-varstrong ESLint . Tùy chọn trình biên dịch này nhằm mục đích loại bỏ và loại bỏ các biến không sử dụng trong Typecript. Hãy xem xét ví dụ dưới đây:

const numHandler = (input: number) => {
  let digits;
  return input;
};

Trong ví dụ trên, chúng ta đã định nghĩa một hàm được gọi numHandler, hàm này nhận một tham số là kiểu số. Tiếp theo, chúng tôi xác định một digitsbiến và trả về tham số đầu vào. Khi chúng tôi biên dịch đoạn mã trên, chúng tôi gặp lỗi bên dưới từ thiết bị đầu cuối:

error TS6133: 'digits' is declared but its value is never read

Lỗi này được tạo ra bởi vì chúng tôi đã khai báo digitsbiến mà không sử dụng nó. Bạn có thể loại bỏ lỗi này bằng cách sử dụng giá trị được khai báo ở đâu đó trong mã hoặc bằng cách đặt tùy chọn trong tệp tsconfig.json thành false.

noUnusedParameter

Tùy chọn trình biên dịch này hơi giống với noUnusedLocalstùy chọn. Sự khác biệt là trong khi noUnusedLocalstạo ra lỗi trên các biến cục bộ không sử dụng, noUnusedParametersẽ tạo ra lỗi khi các tham số hàm được khai báo nhưng không được sử dụng. Hãy xem xét ví dụ dưới đây:

const anExample = (input: string) => {
  const someStrings = 'The name is Isaac'
  return { true, someStrings };
};

Chúng tôi đã định nghĩa một hàm được gọi anExample, hàm này nhận một stringtham số kiểu. Tiếp theo, chúng tôi xác định một biến được gọi someStringsvà sau đó trả về một giá trị boolean và biến đã xác định. Khi chúng tôi biên dịch đoạn mã trên, chúng tôi gặp lỗi bên dưới từ thiết bị đầu cuối:

error TS6133: 'input' is declared but its value is never read

Điều này xảy ra vì chúng ta đã khai báo inputtham số trong hàm mà không sử dụng nó. Bạn có thể loại bỏ lỗi này bằng cách sử dụng tham số được khai báo trong thân hàm hoặc bằng cách đặt tùy chọn trong tsconfig.jsontệp thành false.

noImplicitReturns

Tùy chọn trình biên dịch này đảm bảo rằng bất kỳ hàm nào có khai báo trả về đều trả về một thứ gì đó. Tùy chọn này tạo ra lỗi khi đường dẫn mã trong một hàm không trả về giá trị. Hãy xem xét ví dụ dưới đây:

function add(input: number, output: number) {
  if (input + output > 0) {
    return input + output;
  }
}

Trong ví dụ trên, chúng ta đã định nghĩa một hàm có hai tham số kiểu số. Tiếp theo, chúng ta đặt một câu lệnh if, câu lệnh này sẽ kiểm tra xem tổng của cả hai tham số có lớn hơn 0 hay không và sau đó nó trả về tổng đó. Với tùy chọn trình biên dịch này được đặt thành true, trình biên dịch sẽ tạo ra lỗi loại bên dưới:

error TS7030: Not all code paths return a value.

Typecript phát hiện ở đây rằng không phải tất cả các đường dẫn mã đều trả về thứ gì đó. Không có returntuyên bố nào về thời điểm tổng các đối số không dương và điều này có thể đưa lỗi vào mã của chúng ta vì hàm trên sẽ trả về không xác định. Để giải quyết vấn đề này, hãy đảm bảo rằng tất cả các phần của mã trả về một cái gì đó. Hãy xem xét giải pháp cho đoạn mã trên dưới đây:

function add(input: number, output: number) {
  if (input + output > 0) {
    return input + output;
  }
  return
}

Bằng cách sử dụng từ khóa return, chúng tôi đảm bảo rằng tất cả các phần trong mã của chúng tôi đều trả về một thứ gì đó. Tùy chọn trình biên dịch đã giúp chúng tôi phát hiện tình huống thiếu có thể xảy ra và tránh lỗi.

Phát lại phiên nguồn mở

OpenReplay là một bộ mã nguồn mở, phát lại phiên cho phép bạn xem những gì người dùng làm trên ứng dụng web của bạn, giúp bạn khắc phục sự cố nhanh hơn. OpenReplay được tự lưu trữ để kiểm soát toàn bộ dữ liệu của bạn.

replayer.png

Bắt đầu tận hưởng trải nghiệm gỡ lỗi của bạn - bắt đầu sử dụng OpenReplay miễn phí .

noFallthroughCasesInSwitch

Khi được đặt thành true, tùy chọn trình biên dịch này tạo ra lỗi bất cứ khi nào chúng ta có switchcác câu lệnh chuyển từ nhánh này sang nhánh khác mà không có breakhoặc returntừ khóa. Hãy xem xét ví dụ dưới đây:

let name = 'Isaac';
  
switch (name) {
  case 'Isaac':
    console.log('Isaac is a developer');
  case 'John':
    console.log('John is my friend');
    break;           
}

Khi chúng tôi biên dịch mã ở trên, chúng tôi gặp lỗi bên dưới.

error TS7029: Fallthrough case in switch

Điều này xảy ra bởi vì có một breaktừ khóa bị bỏ qua trong nhánh của switchcâu lệnh đầu tiên. Đôi khi bạn có thể có những lý do hợp lệ để bỏ qua breaktừ khóa đã nói, nhưng đó thường là một lỗi. Một số giải pháp cho điều này là:

  • Đặt noFallthroughCasesInSwitch thành false trong tsconfig.jsontệp
  • Sử dụng // @ts-ignorelệnh để loại bỏ lỗi

strictNullChecks

Tùy chọn trình biên dịch này kiểm tra các trường hợp mà Typecript mong đợi một kiểu cụ thể (số, chuỗi, boolean) nhưng bị null hoặc không xác định khi được đặt thành true. Tùy chọn này giúp chúng tôi loại bỏ Uncaught TypeErrorlỗi. Hãy xem xét ví dụ bên dưới:

let title: string;
name = title;
console.log(name);

Khi chúng tôi biên dịch và chạy đoạn mã ở trên, chúng tôi gặp lỗi bên dưới:

error TS2454: Variable 'title' is used before being assigned

Giải pháp cho lỗi này là gán một giá trị cho biến trước khi sử dụng nó, như chúng ta thấy trong khối mã bên dưới:

let title: string = "Student"
name = title
console.log(name)

noImplicitAny

Mỗi biến trong Typecript đều có một kiểu; hoặc chúng tôi xác định loại hoặc Loại chỉ định cố gắng đoán nó. Hãy xem xét ví dụ dưới đây:

function value(a) {
  return;
}

Trong khối mã ở trên, chúng ta có một hàm với đối số là a; vì chúng tôi không xác định kiểu cho đối số đó, vì vậy, Typescript suy ra rằng đối số có một anykiểu. Với tùy chọn trình biên dịch này được đặt thành true, trình biên dịch sẽ tạo ra lỗi bên dưới:

error TS7006: Parameter 'a' implicitly has an 'any' type

Giải pháp cho điều này là đảm bảo rằng bạn xác định đúng kiểu cho mọi đối số.

noImplicitThis

Với tùy chọn trình biên dịch này được đặt thành true, Typescript sẽ phàn nàn bất cứ khi nào có trường hợp chúng tôi đang sử dụng thistừ khóa không đúng cách hoặc ở một nơi không rõ ràng nơi thisđề cập đến.

class Person {
  weight: number;
  height: number;
  
  constructor(weight: number, height: number) {
    this.weight = weight;
    this.height = height;
  }
  
  getBodyMassIndex() {
    return function () {
      return this.weight / (this.height * this.height);
    };
  }
}

Chúng tôi gặp lỗi bên dưới khi biên dịch mã ở trên do phạm vi trong Javascript. Điều này là do ngữ cảnh của thistừ khóa không bị ràng buộc với bất kỳ trường hợp nào của từ khóa Persontheo mặc định.

error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation

Giải pháp cho điều này là các hàm mũi tên. Điều này sẽ hoạt động vì các hàm mũi tên sử dụng ngữ cảnh thực thi của cha mẹ :

class Person {
  weight: number;
  height: number;
  
  constructor(weight: number, height: number) {
    this.weight = weight;
    this.height = height;
  }
  
  getBodyMassIndex() {
    return () => {
      return this.weight / (this.height * this.height);
    };
  }
}

strictBindCallApply

Tùy chọn trình biên dịch này đảm bảo rằng bạn đang sử dụng call()bind()các apply()hàm với các đối số phù hợp.

const numHandler = (a: number) ={
  console.log(`log ${a}!`);
}

numHandler.call(undefined, 'Isaac')

Khi chúng tôi chạy đoạn mã trên với tùy chọn trình biên dịch này được đặt thành true, chúng tôi gặp lỗi:

error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'

Để giải quyết vấn đề này, chúng ta cần chuyển đối số đúng và lỗi sẽ được giải quyết.

const numHandler = (a: number) ={
  console.log(`log ${a}!`)
}
    
numHandler.call(undefined, '25')

Sự kết luận

Trong bài viết này, chúng tôi đã xem xét một số tùy chọn trình biên dịch, các lỗi mà chúng tạo ra, cách giải quyết chúng và cách cải thiện chất lượng mã bằng cách sử dụng chúng. Nhiều tùy chọn trình biên dịch khác có thể giúp cải thiện chất lượng mã và bạn có thể xem chúng tại đây .

Nguồn: https://blog.openreplay.com/improving-code-quality-in-typescript-with-compiler-options

#typescript 

Jessica Smith

Jessica Smith

1612606870

REAL TIME CHAT SOLUTIONS SERVICES FOR MOBILE APPS

Build a Real Time chat application that can integrated into your social handles. Add more life to your website or support portal with a real time chat solutions for mobile apps that shows online presence indicators, typing status, timestamp, multimedia sharing and much more. Users can also log into the live chat app using their social media logins sparing them from the need to remember usernames and passwords. For more information call us at +18444455767 or email us at hello@sisgain.com or Visit: https://sisgain.com/instant-real-time-chat-solutions-mobile-apps

#real time chat solutions for mobile apps #real time chat app development solutions #live chat software for mobile #live chat software solutions #real time chat app development #real time chat applications in java script

Duong Tran

Duong Tran

1659049200

Cải Thiện Chất Lượng Mã Trong Phần Typecript Phần 2

Chuyển từ JavaScript sang Typescript là một cải tiến lớn trong bất kỳ cơ sở mã nào. Việc chuyển đổi có thể được thực hiện tốt hơn và cải tiến hơn nữa bằng cách vượt ra ngoài các tính năng sắp chữ mặc định, làm cho cơ sở mã của chúng tôi an toàn hơn nhiều. Để thực hiện điều này, chúng ta sẽ cần bao gồm một số tùy chọn trình biên dịch Typecript. Tùy chọn trình biên dịch là các thuộc tính trong tsconfig.jsontệp có thể được bật và tắt để cải thiện trải nghiệm Typecript của chúng tôi. Điều quan trọng cần lưu ý là khi Typecript phát triển, các cờ mới sẽ được tạo ra; do đó, bạn nên xem lại tài liệu sắp chữ và xem liệu có bất kỳ cờ mới nào có thể được bạn quan tâm tại thời điểm đọc tài liệu này hay không.

Bài viết này là phần 2 của Cải thiện chất lượng mã Typecript với các tùy chọn trình biên dịch . Ở đây , chúng tôi sẽ đề cập đến các tùy chọn khác trong tsconfig.jsontệp và cách cải thiện chất lượng mã với các tùy chọn strictPropertyInitialization,,,, và .useUnknownInCatchVariablesstrictFunctionTypesallowUnusedLabelsallowUnreachableCodenoPropertyAccessFromIndexSignatureexactOptionalPropertyTypeforceConsistentCasingInFileNames

Tập tsconfig.jsontin

Tất cả các tùy chọn trình biên dịch được lưu trong tsconfig.jsontệp, được tạo bằng cách chạy tsc --inittrong thiết bị đầu cuối gốc của dự án của chúng tôi. Trong bài đăng này, chúng tôi sẽ thêm các tùy chọn trình biên dịch thường được sử dụng hơn vào tsconfig.jsontệp và chứng minh chức năng mới mà họ giới thiệu cho mã của chúng tôi. Chúng tôi sẽ thêm các tùy chọn trình biên dịch sau để cải thiện chất lượng mã:

"compilerOptions": {
    "module": "system",
    "strictPropertyInitialization": true,
    "useUnknownInCatchVariables": true,
    "strictFunctionTypes": true,
    "allowUnusedLabels": false,
    "allowUnreachableCode": false,
    "noPropertyAccessFromIndexSignature": true,
    "exactOptionalPropertyType": true,
    "forceConsistentCasingInFileNames": true,
    "target": "es5", 
    "module": "commonjs", 
    "rootDir": ".",
    "outDir": "../dist/",
    "sourceMap": true 
}

strictPropertyInitialization

Khi được đặt thành true, tùy chọn trình biên dịch này đảm bảo chúng ta khởi tạo tất cả các thuộc tính của lớp bên trong một phương thức khởi tạo.

class User{
    name: string;
    age: number;
    occupation: string | undefined;
    
    constructor(name: string) {
        this.name = name;
    }
}

Chúng ta có một Userlớp trong khối mã ở trên và phương thức constructor () là nơi chúng ta khởi tạo các thuộc tính của thể hiện của nó. JavaScript tự động gọi phương thức constructor () khi chúng ta khởi tạo một đối tượng lớp. Typecript yêu cầu chúng ta khởi tạo các thuộc tính mà chúng ta đã xác định hoặc chỉ định một kiểu undefined. Do đó, khi chúng tôi biên dịch đoạn mã trên, chúng tôi nhận được lỗi hiển thị bên dưới:

error TS2564: Property 'age' has no initializer and is not definitely assigned in the constructor.

Không thể bỏ qua các biến không xác định trong mã của chúng tôi với tùy chọn này.

useUnknownInCatchVariables

Trong Javascript, chúng ta có thể ném một lỗi và bắt nó trong một catchmệnh đề. Thông thường, đây sẽ là một trường hợp lỗi và được đặt thành anytheo mặc định. Khi useUnknownInCatchVariabletùy chọn trình biên dịch được đặt thành true, nó mặc nhiên đặt bất kỳ biến nào trong catchmệnh đề thành unknownthay vì any. Hãy xem xét ví dụ dưới đây:

try {
    // random code...
      throw 'myException'; 
}
catch (err) {
    console.error(err.message); 
}

Khi chúng tôi biên dịch đoạn mã trên, useUnknownInCatchVariablesđược đặt thành true, nó sẽ thay đổi lỗi của chúng tôi thành một unknownloại. Do đó, chúng tôi nhận được lỗi bên dưới từ thiết bị đầu cuối.

error TS2571: Object is of type 'unknown'.

Lỗi này được tạo ra bởi vì lỗi được đặt thành unknownbởi Typecript. Để khắc phục lỗi này, chúng tôi có thể:

  • Thu hẹp lỗi từ unknownmột trường hợp Lỗi.
try {
  // random code...
    throw 'myException'; 
}
catch (err) { // err: unknown
  if (err instanceof Error) {
    console.error(err.message);
  }
}
try {
  // random code...
  throw "myException";
} catch (err) {
  // Use the type guard
  // error is now narrowed to definitely be a string
  if (typeof err === "string") {
    console.error(err);
  }
}

Với sự trợ giúp của ifkiểm tra của chúng tôi, Typescript nhận ra rằng đó typeof err === "string"là một dạng mã đặc biệt, nơi chúng tôi trình bày và mô tả các loại một cách rõ ràng. Điều này được gọi là bảo vệ loại .

strictFunctionTypes

Khi strictFunctionTypesđúng, các tham số chức năng được kiểm tra kỹ lưỡng hơn. Theo mặc định, các tham số chỉ định là hai biến, ngụ ý rằng chúng có thể vừa là hiệp phương sai vừa là nghịch biến. Phương sai là một cách để có được cái nhìn sâu sắc về các mối quan hệ kiểu con. Khi tham số là hiệp phương sai, chúng ta có thể gán một kiểu cụ thể cho một kiểu rộng hơn (ví dụ: gán một kiểu con cho một kiểu siêu). Tương phản là nghịch đảo; ở đây, chúng ta có thể gán một kiểu rộng hơn cho một kiểu cụ thể (ví dụ: gán siêu kiểu cho một kiểu con). Chúng ta có hiệp phương sai và tương phản trong bivariance. Để tìm hiểu thêm về phương sai, hãy nhấp vào đây .

//strictFunctionTypes: false

interface Animal {
  name: string;
}

interface Dog extends Animal {
  breeds: Array<string>;
}

let getDogName = (dog: Dog) => dog.name;
let getAnimalName = (animal: Animal) => animal.name;

getDogName = getAnimalName;  // Okay
getAnimalName = getDogName;  // Okay

Đoạn mã trên chạy mà không có lỗi và các tham số được so sánh song song theo mặc định. Phương thức của kiểu siêu getAnimalNamevà kiểu con getDogNamecó thể được gán cho nhau. Các tham số của Typescript được so sánh trái ngược nếu strictFunctionTypesđược đặt thànhtrue

//strictFunctionTypes : true

interface Animal {
  name: string;
}

interface Dog extends Animal {
  breeds: Array<string>;
}

let getDogName = (dog: Dog) => dog.name;
let getAnimalName = (animal: Animal) => animal.name;

getDogName = getAnimalName; // Okay
getAnimalName = getDogName; // Error

Khi khối mã trên được chạy, chúng tôi gặp lỗi:

Type '(dog: Dog) => string' is not assignable to type '(animal: Animal) => string'.
Types of parameters 'dog' and 'animal' are incompatible.
Property 'breeds' is missing in type 'Animal' but required in type 'Dog'.

Đây, getAnimalNamelà một chức năng rộng hơn getDogName. Do đó, supertype không thể được gán cho subtype trong trường hợp này. Tuy nhiên, một kiểu con có thể được gán cho một kiểu siêu nhỏ. Hầu hết thời gian, các tham số chức năng phải là tương phản, không phải là hai biến. Nếu chúng ta bật tùy chọn typecript này, thì Typescript sẽ không coi các tham số của hàm là biến thiên.

Phát lại phiên nguồn mở

OpenReplay là một bộ mã nguồn mở, phát lại phiên cho phép bạn xem những gì người dùng làm trên ứng dụng web của bạn, giúp bạn khắc phục sự cố nhanh hơn. OpenReplay được tự lưu trữ để kiểm soát toàn bộ dữ liệu của bạn.

replayer.png

Bắt đầu tận hưởng trải nghiệm gỡ lỗi của bạn - bắt đầu sử dụng OpenReplay miễn phí .

allowUnusedLabels

Một câu lệnh nhãn trong JavaScript được sử dụng để đặt tiền tố cho một nhãn làm số nhận dạng. Các câu lệnh nhãn trong JavaScript tương tự như các điểm kiểm tra trong mã của chúng tôi. Vì từ khóa nhãn không phải là từ khóa dành riêng trong JavaScript, chúng tôi có thể biểu diễn nó bằng bất kỳ chuỗi nào không phải là từ dành riêng và được theo sau bởi dấu hai chấm :. Cú pháp khai báo nhãn tương tự như cú pháp khai báo một đối tượng trong JavaScript. Hầu hết các nhà phát triển mắc lỗi khai báo nhãn thay vì đối tượng. Để tránh điều này, Typescript cung cấp cho chúng tôi allowUnusedLabelstùy chọn, khi được đặt thành false, sẽ khiến cho Typescript gặp lỗi đánh dấu bất kỳ nhãn nào không được sử dụng trong mã của chúng tôi.

const isUserAgeValid = (age: number) => {
  if (age > 18) {
    curfew: true; //-- COMPILER ERROR - Unused label
  }
};

Trong đoạn mã trên, curfewlà một nhãn. Lỗi sau sẽ xuất hiện khi khối mã được biên dịch:

error TS7028: Unused label

allowUnreachableCode

Mã UnReachable sẽ không bao giờ được thực thi, chẳng hạn như mã theo sau một câu lệnh trả về. Khi tùy chọn trình biên dịch này được đặt thành true, các mã không thể truy cập được sẽ bị bỏ qua. Ngược lại, TypeScript xác minh các đường dẫn mã của chúng tôi khi allowUnreachableCodeđược đặt thành false, đảm bảo rằng tất cả các mã đều có thể được truy cập và sử dụng. Khi được đặt thành true, lỗi sẽ xảy ra nếu phát hiện thấy bất kỳ mã không thể truy cập nào.

const randomNum = (n: number): boolean => {
  if (n > 5) {
    return true;
  } else {
    return false;
  }
    
  return true;
};

Nếu một đoạn mã được chứng minh là không thể truy cập được, thì Typescript sẽ hiển thị cảnh báo này:

error TS7027: Unreachable code detected.

noPropertyAccessFromIndexSignature

Khi tùy chọn trình biên dịch này được đặt thành true, nó yêu cầu chúng ta truy cập các thuộc tính không xác định bằng cách sử dụng []ký hiệu dấu ngoặc và .dotký hiệu để truy cập các thuộc tính đã xác định. Điều này thúc đẩy tính nhất quán vì thuộc tính được truy cập bằng ký hiệu dấu chấm luôn cho biết thuộc tính hiện có. (obj.key) syntaxTrong khi chúng tôi sử dụng ký hiệu dấu ngoặc [] nếu thuộc tính không tồn tại. obj["key"].

interface HorseRace {
  // defined properties
  breed: "Shetland" | "Hackney" | "Standardbred";
  speed: "fast" | "slow";

  //index signature for properties yet to be defined
  [key: string]: string;
}

declare const pick: HorseRace;

pick.breed;
pick.speed;
pick.ownerName;

Trong ví dụ trên, chúng tôi đã xác định một giao diện HorseRacevà cung cấp cho nó một số thuộc tính như giống, tốc độ và chữ ký chỉ mục (đối với các thuộc tính không xác định). Chúng tôi gặp lỗi này khi biên dịch mã ở trên.

error TS4111: Property 'ownerName' comes from an index signature, so it must be accessed with ['ownerName'].

Để sửa lỗi này, hãy sử dụng ký hiệu ngoặc khi gọi thuộc tính ownerName.

pick.breed;
pick.speed;
pick["ownerName"]

exactOptionalPropertyType

Theo mặc định, Typecript bỏ qua việc một thuộc tính được đặt thành “không xác định” vì nó không được xác định hay vì chúng tôi đặt nó theo cách đó.

//exactOptionalPropertyTypes = false

interface Test {
  property?: string;
}

const test1: Test = {};
console.log("property" in test1); //=> false

const test2: Test = { property: undefined };
console.log("property" in test2);

Khối mã trên sẽ thực thi mà không có lỗi, ghi nhật ký falsetruecác giá trị. Trong test1, chúng tôi đang kiểm tra xem liệu propertyđã được xác định chưa; nếu không, nó ghi nhật ký a false. Trong test2, giá trị trueđược ghi lại bởi vì chúng tôi đã xác định propertyvà đặt propertythành undefined. Tiếp theo, hãy đặt exactOptionalPropertyTypestùy chọn thành true.

//exactOptionalPropertyTypes = true

interface Test {
  property?: string;
}

const test1: Test = {};
console.log("property" in test1); // false

const test2: Test = { property: undefined };
console.log("property" in test2);  // true

Khi khối mã trên được biên dịch, lỗi sau sẽ được ghi lại:

error TS2375: Type '{ property: undefined; }' is not assignable to type 'Test' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'property' are incompatible. Type 'undefined' is not assignable to type 'string'.

Điều đã xảy ra ở đây là Typecript từ chối cho chúng tôi định nghĩa một propertytrong số undefined. Nếu propertykhông được chú thích rõ ràng cho một loại undefinedđầu tiên. Để giải quyết vấn đề này, chúng ta có thể chú thích propertyvới loại undefined.

//exactOptionalPropertyTypes = true

interface Test {
  property?: string | undefined;
}

const test1: Test = {};
console.log("property" in test1); //false

const test2: Test = { property: undefined };
console.log("property" in test2);  //true

Mã của chúng tôi chạy trơn tru trở lại, ghi nhật ký falsetruecác giá trị. Typecript nhận biết được hai cách khác nhau này để có một thuộc tính không xác định khi exactOptionalPropertyTypesđược kích hoạt. Nó cũng đảm bảo rằng nếu chúng ta muốn xác định rõ ràng một thuộc tính là undefined, thì trước tiên nó phải được chú thích với kiểu undefined.

forceConsistentCasingInFileNames

Đây là một tùy chọn trình biên dịch rất được khuyến khích giữa các nhóm và nó khuyến khích các thành viên trong nhóm sử dụng các phương pháp hay nhất và nhất quán. Khi tùy chọn này được đặt thành false, các quy tắc phân biệt chữ hoa chữ thường của hệ điều hành (OS) mà tệp Typecript đang chạy sẽ được tuân theo. Nó có thể phân biệt chữ hoa chữ thường (hệ điều hành phân biệt giữa các ký tự viết thường và viết hoa trong tên tệp) hoặc không phân biệt chữ hoa chữ thường (hệ điều hành không phân biệt giữa các ký tự). Khi forceConsistentCasingInFileNamestùy chọn được đặt thành true, Typescript sẽ xuất hiện lỗi Nếu chúng tôi cố gắng nhập tệp có cách viết hoa tên khác với cách viết hoa tên tệp trên đĩa.

// StringValidator.ts

export interface StringValidator {
  isAcceptable(s: string): boolean;
}
// ZipCodeValidator.ts

import { StringValidator } from "./stringValidator";

export const numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements StringValidator {
  isAcceptable(s: string) {
    return s.length === 5 && numberRegexp.test(s);
  }
}

Không xem xét trường hợp tên của tệp, chúng tôi nhập StringValidatortệp trong mã ở trên. Nếu forceConsistentCasingInFileNamestùy chọn được đặt thành true, lỗi sẽ xuất hiện:

error TS1149: File name 'C:/Users/acer/Desktop/workBase/writing/Typescript/tsc/stringValidator.ts' differs from already included file name 'C:/Users/acer/Desktop/workBase/writing/Typescript/tsc/StringValidator.ts' only in casing.

Để giải quyết vấn đề này, hãy sử dụng ký tự viết hoa chính xác cho tên tệp của bạn khi nhập.

Sự kết luận

Bài viết này đã xem xét một số tùy chọn trình biên dịch, các lỗi mà chúng tạo ra, cách giải quyết chúng và cách cải thiện chất lượng mã bằng cách sử dụng chúng. Bạn có thể tìm thấy nhiều tùy chọn trình biên dịch khác có thể giúp nâng cao chất lượng mã tại đây .

 Nguồn: https://blog.openreplay.com/improving-code-quality-in-typescript-with-compiler-options-part-2

#typescript 

Alex  Sam

Alex Sam

1576484092

Drive Engagement and Interaction Voluntarily via Team Collaboration Chat Apps

Emails are almost extinct. The need to stay glued to your office desk is no more a necessity to stay connected with teams. Chat applications are here and are changing the way teams collaborate and communicate with each other with increased mobility.

Chats have gone a long way from being reserved only for socializing purposes to hosting important team discussions and meetings where ideas are born and rolled out. Team chat apps built for iOS and Android devices are the new collaborative tools that business people thrive on.

Chat apps solutions are seeing technical teams in technology companies, be it startups or an enterprise-grade companies as early adopters as they have started realizing the benefits of flexible and frictionless communication that these chat solutions power.

Advantages that Pose Real-time Instant Messaging Apps as Convenient Alternatives for Group or Team Communication Over Conventional emailing Systems

1. Ad-hoc Conversations
Apart from bringing employees together chat apps pave way for grouping teams for ad-hoc conversations where technical people can discuss over tasks, brainstorm and come up with ideas.

2. Epicenter of Tasks
Through an array of integrations that chat applications offer, teams, especially those involved in product development, can centralize their accounts on other collaborative platforms like GitHub, Jira into the chat application itself creating an ecosystem that caters to all collaboration purposes.

3. Record Keeping and Easy Search
Key developments that happen over a verbal discussion need to be noted down else chances are more likely for losing a crucial breakthrough achieved over a brainstorming session. Team collaboration chat apps record every improvement and contents that dates back to any time can be fully searched.

4. Switch Over Devices Based on Convenience
Multi device compatibility ensures that your employees are connected with teams no matter what devices they are using. If on-the-go connectivity is your preference, get things done on smartphone. If convenience matters the most, switch over to your desktop and continue from where you left.

5. Multiple Communication Medium
Text messages, voice calls, video calls, VOIP calls, direct messages, group chats on iOS and Android extend the modes and medium through which you can get to communicate with your peers, teams and entire organization for that matter.

6. Everything Else that Count
Adding to these, features like file sharing (multiple file types), video conferencing, opinion generation through polls, task delegation, followups, update, personalized notification settings, reminders, to-do list creation and much more can be done through real-time team chat applications.

However, the limitations of team collaboration chat apps end here only if you think so. With every other team, apart from development teams, like those that operational level, management level, marketing level etc can also get to reap the benefits of chat apps. Read on to know the

Instances Which Chat Apps Prove Useful for All Teams in an Organization

Why restrict the benefit of real-time instant messaging chat app to only technology teams into development and designing. Every other team in your office or organization can get a fair share of its advantages.

Here are some of the instances where chat apps can be useful for other teams.
Human Resource team can build employee engagement programs. HRs can get fast response from employees, build a powerful relationship with them, conduct opinion poll for decision making. The hardly-used suggestion box in office premises can be replaced by a chat app for a more effective and instant feedback.

An organization’s system administration team can stay connected with employees on the go and be there on time to resolve issues. Moreover, notifications on breakdowns and other technical issues can help in saving the downtime. Alerts and reminders on instant messaging applications can contribute towards proactive care.

For marketing professionals and sales executives, chat apps on multiple platforms like iOS, Android can reduce series of mail threads into chat logs that are easily searchable. Live video calls and voice calls can help them build better client relationship and both pre and post sales support can get more livelier and personalized with chat apps.

At operational level, chat apps can connect an organization’s representative with many third party vendors to keep up on timely delivery, maintenance, bill payments and more.

Group or Team collaboration applications are the new age communication tools that can contribute for successful communication between employees of an organization in multiple angles. From initiating an idea to getting works done, real time chat apps have started helping organization at many instances which are tough to handle when done conventionally.

If you are into an organization but still have not got a chat app on board, it is high time that your build a chat app on iOS and Android.

#Team Collaboration Chat Apps #real time chat apps #build a chat app #real-time instant messaging chat app #Chat apps solutions