本篇内容主要讲解“TypeScript泛型的相关知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“TypeScript泛型的相关知识点有哪些”吧!
1、ts的泛型很难吗?
如果你:
刚开始学ts
刚开始接触泛型
正在挣扎得学习ts的泛型
看到以下代码有没有很疑惑?
function makePair< F extends number | string, S extends boolean | F >()
Java是和typescript一样支持泛型的,当我在大学开始学习Java的时候,我还是一个菜鸟码农,遇到难点(比如泛型)就直接跳过,能学多少学多少,回寝室就LOL开黑。直到大学毕业我依旧没有理解泛型的概念,可能你和我一样觉得泛型很难,下面我会分享我的理解,希望对你有所帮助。
2、一起来看一下makeState()这个函数
首先,我写了makeState这个函数,我们会用这个函数来讨论泛型
function makeState() { let state: number function getState() { return state } function setState(x: number) { state = x } return { getState, setState } }
当你运行这个函数,我们会得到getState() 和 setState()这两个函数。
让我们来试一下,下面这段代码会打印出什么
const { getState, setState } = makeState() setState(1) console.log(getState()) setState(2) console.log(getState())
1 2
会打印出1和2,没那么难对吧?
Note: 如果你正在使用react,你可能会发觉,makeState()和钩子函数useState()很像。这里也涉及到了闭包和ES6的解构赋值
3、我们传入字符串会如何?
我们把刚才给setState的入参1和2替换成字符串'foo'会输出什么呢?
const { getState, setState } = makeState() setState('foo') console.log(getState())
Argument of type '"foo"' is not assignable to parameter of type 'number'.
会编译失败,因为setState()需要的参数类型是number
我们可以用以下方法解决这个问题
function makeState() { // Change to string let state: string function getState() { return state } // Accepts a string function setState(x: string) { state = x } return { getState, setState } }
const { getState, setState } = makeState() setState('foo') console.log(getState())
foo
4、挑战:获取两个不同类型的state
我们能不能修改makeState()这个函数,来输出两个不同类型的state,比如一个是字符串,一个是数字。
以下代码简略得表示我想表达的意思:
// One that only allows numbers, and… const numState = makeState() numState.setState(1) console.log(numState.getState()) // 1 // The other that only allows strings. const strState = makeState() strState.setState('foo') console.log(strState.getState()) // foo
要达到以上效果,我们可能需要创建两个内部不一样的makeState(),一个state的类型是数字,一个是字符串。
怎么用才能只写一个来实现呢?
5、实验一:设置多个类型
这是我们的第一个尝试:
function makeState() { let state: number | string function getState() { return state } function setState(x: number | string) { state = x } return { getState, setState } }
const numAndStrState = makeState() //数字 numAndStrState.setState(1) console.log(numAndStrState.getState()) //字符串 numAndStrState.setState('foo') console.log(numAndStrState.getState())
1 foo
结果看上去我们貌似成功了,但是这并不是我真实想要的,我们真正要实现的是只能输出数字state和只能输出字符串state。
numAndStrState是既能输出数字类型,又能输出字符串类型
6、实现二:使用泛型
接下来我们的泛型要登场了:
function makeState<S>() { let state: S function getState() { return state } function setState(x: S) { state = x } return { getState, setState } }
makeState() 被定义成 makeState<S>(),你可以把<S>当作函数参数,但它传入的不是值,而是类型。
比如你可以传入数字类型:
makeState<number>()
在makeSate()这个函数内部state会变成数字类型
let state: S // <- number function setState(x: S /* <- number */) { state = x }
这样就实现了只能输出数字state
// Creates a number-only state const numState = makeState<number>() numState.setState(1) console.log(numState.getState()) // numState.setState('foo') 输入字符串foo会报错
同理我们也可以实现只能输出字符串state
// Creates a string-only state const strState = makeState<string>() strState.setState('foo') console.log(strState.getState()) // strState.setState(1) 输入数字1会报错
Note: 我们把makeState<S>()称作泛型函数,就是一个普通的函数支持类型参数的传入
你可能会疑惑为什么类型参数是S, 其实随便什么都可以,但是通常来说我们会用一个变量的第一个字母的大写来代表这个变量的类型:
T(for“T”ype)
E(for“E”lement)
K(for“K”ey)
V(for“V”alue)
7、泛型的类型范围限制
目前,在我们改进下的makeState()实现了只能输出数字state和只能输出字符串state。但是它也能实现输出布尔值。
// Creates a boolean-only state const boolState = makeState<boolean>() boolState.setState(true) console.log(boolState.getState())
问题:那么我们要如何限制它就只能输入输出number和string类型呢?
方法:声明makeState()这个函数时,把类型参数<S>变为<S extends number | string>,这样就只能输入number或者string类型了
function makeState<S extends number | string>() { let state: S function getState() { return state } function setState(x: S) { state = x } return { getState, setState } } // 如果我传入boolean类型 const boolState = makeState<boolean>()
Type 'boolean' does not satisfy the constraint 'string | number'.
8、泛型的默认类型
现在每次调用makeState()时,我们可以任意传入<number> 或<string>类型,那怎么设置一个默认类型呢?
比如让下面两个语句起到相同的作用:
const numState1 = makeState() const numState2 = makeState<number>()
其实和给函数参数设置默认值一样:
function makeState<S extends number | string = number>()
这样,变量state默认类型就是number了
const numState = makeState() numState.setState(1) console.log(numState.getState())
到此,相信大家对“TypeScript泛型的相关知识点有哪些”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。