typescript使用心得
javascript中的问题
传参错误
const { buy } = require('./buy.js')
const person = {
name: '张三',
store: [],
}
const goods = {
name: '橄榄油',
unit: '瓶',
price: 1,
}
buy(person, goods) // 张三买了一瓶橄榄油
// ...
buy(goods, person) // 橄榄油买了一undefined张三
function buy(person, goods) {
person.store = person.store || []
person.store.push(goods)
console.info(`${person.name}买了一${goods.unit}${goods.name}`)
}
exports.buy = buy
buy.js
index.js
javascript
buy.ts
import { Person, Goods } from './types'
function buy(person: Person, goods: Goods): void {
person.store = person.store || []
person.store.push(goods)
console.info(`${person.name}买了一${goods.unit}${goods.name}`)
}
export { buy }
types.ts
interface Person {
name: string,
store: any[]
}
interface Goods {
name: string,
unit: string,
price: number
}
export { Person, Goods }
typescript
index.ts
import { Person, Goods } from './types'
import { buy } from './buy'
const person: Person = {
name: '张三',
store: [],
}
const goods: Goods = {
name: '橄榄油',
unit: '瓶',
price: 1,
}
buy(person, goods)
// buy(goods, person)
// Argument of type 'Goods' is not assignable to parameter of type 'Person'.
javascript
17
typescript
30
统计
实现相同功能, 使用代码行数(去除空行, 注释行错误代码)
javascript中的问题
空值问题, 拼写错误
const stuffs = [
{
type: 'pm',
sayHi() {
console.info(`wang wang wang`)
},
},
{
type: 'fed',
sayHi() {
console.info(`我是前端`)
},
},
{
type: 'bed',
sayHi() {
console.info(`我是后端`)
},
},
]
function findStuff(type) {
return stuffs.find(stuff => stuff.type === type)
}
findStuff('pm').sayHi()
findStuff('hr').sayHi()
// TypeError: Cannot read property 'sayHi' of undefined
findStuff('pm').sayHI()
// TypeError: stuffs.find(...).sayHI is not a function
javascript
interface Stuff {
type: string
sayHi: () => void
}
const stuffs: Stuff[] = [
{
type: 'pm',
sayHi(): void {
console.info(`wang wang wang`)
},
},
{
type: 'fed',
sayHi(): void {
console.info(`我是前端`)
},
},
{
type: 'bed',
sayHi(): void {
console.info(`我是后端`)
},
},
]
typescript
// Type 'Stuff | undefined' is not assignable to type 'Stuff'.
// Type 'undefined' is not assignable to type 'Stuff'.
// function findStuff(type: string): Stuff {
// return stuffs.find((stuff: Stuff) => stuff.type === type)
// }
function findStuff(type: string): Stuff | undefined {
return stuffs.find((stuff: Stuff) => stuff.type === type)
}
findStuff('pm').sayHi() // Object is possibly 'undefined'
const stuff: Stuff | undefined = findStuff('pm')
if (stuff) {
stuff.sayHI()
// Property 'sayHI' does not exist on type 'Stuff'. Did you mean 'sayHi'?
}
"compilerOptions": { "strictNullChecks": true }
统计
typescript - javascript = interface declaration
interface Stuff {
type: string
sayHi: () => void
}javascript中的问题
enum
const Color = {
RED: 1,
GREEN: 2,
BLUE: 3,
}
const shirt = {
color: Color.RED,
}
console.info(shirt.color) // 1
function foo(color) {
switch (color) {
case Color.RED:
console.info(`the color is red`)
break
default:
console.info(`invalid color`)
}
}
foo(shirt.color)
foo('red')
foo(6)
javascript
typescript
enum Color {
RED,
GREEN,
BLUE,
}
const shirt: any = {
color: Color.RED,
}
console.info(shirt.color) // 0
function foo(color: Color): void {
switch (color) {
case Color.RED:
console.info(`the color is red`)
break
default:
console.info(`invalid color`)
}
}
foo(shirt.color)
foo('red')
// Argument of type '"red"' is not assignable to parameter of type 'Color'
foo(6) // valid
enum Color {
RED = 'red',
GREEN = 'green',
BLUE = 'blue',
}
const shirt: any = {
color: Color.RED,
}
console.info(shirt.color) // red
function foo(color: Color): void {
switch (color) {
case Color.RED:
console.info(`the color is red`)
break
default:
console.info(`invalid color`)
}
}
foo(shirt.color)
foo('red')
// Argument of type '"red"' is not assignable to parameter of type 'Color'
foo(6)
// Argument of type '6' is not assignable to parameter of type 'Color'
decorator
更清晰的代码
feedback app.js
typescript无法(不好)解决的问题
ajax获得的数据
request(url, {
onload(data) {
if (data.success) {
const aaa = data.xxx
aaa.foo() // aaa == null aaa.foo is not a function
}
}
})interface ResponseData {
xxx: {
foo: Function
}
}
request(url, {
onload(data: ResponseData) {
if (data.success) {
const aaa = data.xxx
aaa.foo()
}
}
})declaration hell
随着响应中的数据结构越来越复杂, 声明将变得越来越大
结论
1. 不是点石成金, 而是五鬼搬运
typescript虽然提供了类型检查的便利, 但这是以用户预先定义好变量类型为前提的.
比如用户没有做非空判断, 或者拼写的错误, 都会在开发过程中得到IDE的错误提示或在编译过程中得到编译器的报错. 但是保证这一切的前提是用户编写了详细准确的声明文件, 以及在声明变量时写好类型. 各种可能抛错的条件进行判断的工作量依然没有改变, 只是转移了地方.
不过值得高兴的是, 声明文件一般只需要编写一次, 在后续的维护开发中, 这部分工作是很少会大量重复的. 所以抛开声明文件不说, 唯一使ts代码量比js代码量大的地方, 也就只剩声明变量时的 :{type}了
此外, 得益于ts的静态类型特性, 在IDE中用户可以方便的跳转到方法的定义处, 或hover查看方法的参数表甚至doc等, 这是js开发环境难以做到的. 但是这些特性无法在OLOO方式的继承中使用.
2. 适合代码量大, 结构复杂的项目
3. 对编码仔细, 判空严谨的人, 过多的声明反而成为一种负担
Thank you
deck
By fuucker
deck
- 22