typescript 通过 interface 定义函数,如何限制函数的返回值为接口定义的精确类型呢 ? ts: 4.6.2

image.png

interface API {
  (): { token: string };
}

const api: API = function () {
  const a: ReturnType<API> = {
    token: "",
    /** 这里报错 */
    a: " ",
  };
    /** 这里不报错 */
  return {
    token: "",
    a: " ",
  };
};
阅读 2.5k
1 个回答

之前旧的回答理解错了

题主想要的效果,个人感觉其实是不太符合逻辑的,或者说这种情况在ts类型中是没毛病的,正常的

我有一个方法 getUserInfo() 返回了对象类型 { name: string, age: number }

我把这个方法赋值给一个新方法 getUserInfoName = getUserInfo 规定getUserInfoName的类型只能返回 {name: string} 这个操作是兼容的

跟下面这个例子同理:

type Info = {
    name: string,
    age: number
}

type NameInfo = {
    name: string
}


const info: Info = {
    name: '1111',
    age: 2222
}

// 不会有任何报错
const nameInfo: NameInfo = info

nameInfo.age // 报错

info 又不知道自己要被赋值给谁

假如在js nameInfo = info 然后调用 nameInfo.age 有问题吗?本来就没问题

tsnameInfo: NameInfo = info 赋值没问题是因为这种操作是兼容的,然后调用 nameInfo.age ts 就会报错,其他的key你不用不就行了

下面是各种情况:在线例子

// 不报错
const nameFn1: (name:string) => void = function(name: string) {}

// 报错,参数不兼容
const nameFn2: (name:string) => void = function(name: number) {}

// 报错,返回值的key
const nameFn3: () => { age: number } = function() {
    return {
        name: 123
    }
}

// 报错,返回值的key的类型不兼容
const nameFn4: () => { name: string } = function() {
    return {
        name: 123
    }
}

// 不报错,返回值兼容
const nameFn5: () => { name: string } = function() {
    return {
        name: 'nnnn',
        age: 123
    }
}
// 赋值兼容不抛错,但是调用会报错
nameFn5().age

旧回答:

可以写一个高级类型,类似于ReturnType的增强,给函数类型返回值类型替换一下

interface API {
  (): { token: string };
}

type ReturnAnd<T extends (...args: any) => any, R> = (...args: Parameters<T>) => ReturnType<T> & R
type ReturnOr<T extends (...args: any) => any, R> = (...args: Parameters<T>) => ReturnType<T> | R
type ReturnReplace<T extends (...args: any) => any, R> = (...args: Parameters<T>) => R

const api: ReturnAnd<API, { a: string }> = function () {
  const a = {
    token: "",
    a: " ",
  };

  return a
};


api().a
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏