更窄的类型不能分配给其他
More narrow type is not assignable to other
有两种类型:
type ExcludeString<T = any> = Exclude<T, string>;
type ExcludeStringAndBoolean<T = any> = Exclude<T, string | boolean>;
在函数的代码中
function test1<T>(p: ExcludeStringAndBoolean<T>) {
let a: ExcludeString<T>;
a = p;
}
tsc 为第 a = p
行抛出错误
Type 'Exclude<T, string | boolean>' is not assignable to type 'Exclude<T, string>'.ts(2322)
但对于特定用途来说效果很好:
type CertainType = string | number | boolean;
function test2(p: ExcludeStringAndBoolean<CertainType>) {
let a: ExcludeString<CertainType>;
a = p;
}
为什么会这样?
Exclude
是条件类型。如果条件类型包含未解析的类型参数(例如 T
),typescript 将不会尝试对条件类型进行太多推理。所以可分配性规则变得非常严格。
对于 Exclude
,如果第二个参数不同(即测试的类型不同),则可分配性检查失败(例如 string | boolean
与 string
在您的情况下)。如果第一个参数(即测试类型)有类型关系,则赋值成功。因此,例如这将起作用:
type ExcludeString<T = any> = Exclude<T, string>;
type ExcludeStringAndBoolean<T = any> = Exclude<T, string | boolean>;
function test1<T extends U, U>(p: ExcludeString<T>) {
let a: ExcludeString<U>;
a = p;
}
有两种类型:
type ExcludeString<T = any> = Exclude<T, string>;
type ExcludeStringAndBoolean<T = any> = Exclude<T, string | boolean>;
在函数的代码中
function test1<T>(p: ExcludeStringAndBoolean<T>) {
let a: ExcludeString<T>;
a = p;
}
tsc 为第 a = p
Type 'Exclude<T, string | boolean>' is not assignable to type 'Exclude<T, string>'.ts(2322)
但对于特定用途来说效果很好:
type CertainType = string | number | boolean;
function test2(p: ExcludeStringAndBoolean<CertainType>) {
let a: ExcludeString<CertainType>;
a = p;
}
为什么会这样?
Exclude
是条件类型。如果条件类型包含未解析的类型参数(例如 T
),typescript 将不会尝试对条件类型进行太多推理。所以可分配性规则变得非常严格。
对于 Exclude
,如果第二个参数不同(即测试的类型不同),则可分配性检查失败(例如 string | boolean
与 string
在您的情况下)。如果第一个参数(即测试类型)有类型关系,则赋值成功。因此,例如这将起作用:
type ExcludeString<T = any> = Exclude<T, string>;
type ExcludeStringAndBoolean<T = any> = Exclude<T, string | boolean>;
function test1<T extends U, U>(p: ExcludeString<T>) {
let a: ExcludeString<U>;
a = p;
}