请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

rest参数的类型检验

老师,您好,有一个问题想请教您一下。

代码如下:


class Person {

    name: string

    age: number

    constructor(name: string, age: number) {

        this.name = name

        this.age = age

    }

}

function createInstance<T>(ctor: new (...params) => T, ...args): T {

    return new ctor(...args)

}

const person = createInstance<Person>(Person, 123, 20) // should be error: 类型“123”的参数不能赋给类型“string”的参数

console.log(person.name) // 123

console.log(person.name.length) // undefined


我的问题是:

1、Person的constructor方法中,name参数应该是字符型;但在createInstance<Person>(Person, 123, 20) 中传入的123是number类型,但是typescript没有提示类型错误,导致person.name.length为undefined。

2、如何给rest参数...params进行类型校验?


正在回答

1回答

同学你好,ts 没办法,进入函数体内,进行参数校验,你可以在 createInstance 的 ...args 进行校验,语法和其他一样 ...args: string[]

虽然 person.name 其实是个数字,但是 Person类上 的name 属性定义是个string 类型,所以ts 没有办法校验出来这个错误。你返回的是 Person 的实例,它自然以为 name 是字符串

0 回复 有任何疑惑可以回复我~
  • 提问者 慕粉1845456658 #1
    老师,您好。我现在对...args使用了元祖[string, number],校验正确了。但是这样只能写死在createInstance中,不够灵活。所以我想使用泛型的方法对...args进行检验。在泛型使用元祖后,ts提示错误。
    
    function createInstance<T, U> (ctor: new (...params) => T, ...args: U): T { // error: rest 参数必须是数组类型
      return new ctor(...args) // error: 类型“U”必须具有返回迭代器的 "[Symbol.iterator]()" 方法
    }
    const person = createInstance<Person, [string, number]>(Person, 'person', 25)
    
    这个有什么解决的方法呢?
    回复 有任何疑惑可以回复我~ 2020-05-03 12:34:55
  • 张轩 回复 提问者 慕粉1845456658 #2
    同学 我觉得你做的真的很棒 能一直深挖下去,其实已经很接近了,我们之前学了泛型的约束啊,我们需要约束 U 的类型,必须是个数组才可以。那么就简单改一下
    
    function createInstance<T, U extends any[]>(ctor: new (...params) => T, ...args:U): T {
    
      return new ctor(...args)
    
    }
    回复 有任何疑惑可以回复我~ 2020-05-06 10:24:03
  • 提问者 慕粉1845456658 #3
    非常感谢!
    回复 有任何疑惑可以回复我~ 2020-05-12 21:20:46
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信