You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中提取类型内函数时参数逆变未生效,如何禁用非法赋值?

TypeScript strictFunctionTypes下方法类型与独立函数类型的兼容性差异

1. 为何all = lim无报错而all2 = lim2触发错误?

TypeScript在strictFunctionTypes模式下,对两类函数类型的兼容性规则做了区分:

  • 独立函数类型(如(s: string) => string)严格遵循参数逆变:目标函数接受更宽泛的参数类型时,源函数的参数类型必须是目标参数的超集才能赋值。all2接受任意string,但lim2只接受"bar"字面量,无法处理所有string输入,因此赋值报错。
  • 对象/类的方法类型(如Foo['getData']这种从对象属性提取的方法)默认采用双向协变:这是TypeScript为兼容旧代码保留的例外规则,既允许逆变也允许协变。所以接受"bar"的lim可以赋值给接受string的all,不会触发错误。

2. 如何禁止all = lim的非法赋值?

要让对象中的函数类型严格遵循strictFunctionTypes的逆变规则,只需将对象中的方法定义改为箭头函数类型(替换原有的方法语法),这样TypeScript会将其视为普通函数类型而非方法类型:

type Foo = {
  getData: (s: string) => string; // 用箭头函数类型定义属性
}

type Bar = {
  getData: (s: "bar") => string;
}

declare let all: Foo['getData'];
declare let lim: Bar['getData'];

all = lim; // 现在会触发预期的类型错误:Type '"bar"' is not assignable to type 'string'
lim = all;

修改后,Foo['getData']和Bar['getData']会被解析为普通函数类型,严格应用参数逆变规则,此时all = lim就会和all2 = lim2一样触发报错,符合你的预期。


内容的提问来源于stack exchange,提问作者CRice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:15:56