[] Null、Undefined和Never是其它类型的子类型,因此可以赋值给任何其它类型变量 (摘自基本类型_TypeScript笔记2) 也就是说,要确定数组类型的话,先要确定每个元素的类型,再考虑其兼容关系...,以确保类型安全,因此: // 把父类型赋值给子类型,在逆变的场景中是安全的 dogComparer = animalComparer; // Ok // 把子类型赋值给父类型,在逆变的场景(函数类型...以保证目标函数可以在所有源函数可调用的地方调用,例如: interface sum { (a: number, b: number): number; (a: number[]): number;...return y; }// 正确 等价于把(y: any) => any赋值给(x: any) => any identity = reverse; 七.类型兼容性 实际上,TypeScript规范中只定义了...赋值兼容性扩展了子类型兼容性,允许any相互赋值,以及enum和对应数值相互赋值 至于类型兼容性,规范中并未定义这个概念,在多数语境下,所谓的类型兼容性遵从赋值兼容性,implements和extends
type PersonName = Person["name"]; // string 但是,更有趣的是,我们也可以从泛型和函数中提取类型。...V : never type StrDictMember = DictMember 在 TypeScript 2.8 中引入了条件类型,使得我们可以根据某些条件得到不同的类型,这里所说的条件是类型兼容性约束...X : Y 以上表达式的意思是:若 T 能够赋值给 U,那么类型是 X,否则为 Y。这很好理解,但在 T extends Dictionary ?...no match for the signature '(...args: any): any'. type T7 = ReturnType; // Error 为什么 ReturnType...U : never; type Fn1Arg = ArgType; // number 如果你想要抽取函数中元组类型的所有参数的类型,这就变得更加有趣,在 TypeScript 3.0 版本之后
可以选择给其声明为any或者unkown。...注意,只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候: interface Person { readonly id: number; name: string...{ name: string; } interface Cat extends Animal { run(): void; } 那么也不难理解为什么 Cat 类型的 tom 可以赋值给... Animal 类型的 animal 了——就像面向对象编程中我们可以将子类的实例赋值给类型为父类的变量。...则会报错,不允许将 animal 赋值为 Cat 类型的 tom。 这很容易理解,Animal 可以看作是 Cat 的父类,当然不能将父类的实例赋值给类型为子类的变量。
但这个函数并不是可以扩展或通用的。 虽然可以使用 any 解决通用性问题,但那就失去了定义应该返回那种类型的能力,并且也使编译器失去了类型保护的作用。...,只要它指定了默认类型 # 泛型条件类型 条件类型可以根据某些条件得到不同的类型,这里的条件值类型兼容性约束。...虽然之前代码中使用了 extends 关键字,但也不一定要强制满足继承关系,而是检查是否满足结构兼容性。 // 若 T 能赋值给 U 那么类型是 X,否则是 Y T extends U ?...如,never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头表达式的返回值类型。 没有类型是 never 的子类型或可以赋值给 never 类型(除了 never 本身)。...定义 // 如果 T 能赋值给 U,那么就会返回 never 类型,否则返回 T 类型 // 最终实现的效果就是将 T 中某些属于 U 的类型移除掉 type Exclude = T extends
类型 在 TypeScript 中,任何类型都可以赋值给 any 类型,这让 any 类型成为了 TypeScript 中的顶级类型。...一旦你将变量指定为 any 类型,你就可以在它上面调用任何方法,访问任何属性,或者作为函数调用它。...为了解决 any 带来的问题,TypeScript 3.0 引入了 unknown 类型。 unknown 类型与 any 类型相似,所有类型也都可以赋值给 unknown 类型。...但是,当我们尝试将类型为 unknown 的变量赋值给其他变量时,TypeScript 会报错。...unknown 类型的值,因为不知道变量 value 的类型,所以不能将它赋值给其他类型的变量。
, 可以赋值给其他类型的变量 strictNullChecks 为 true 的话不能赋值给其他类型 let str: string; str = null; str = undefined; 任意类型...:void => {} never 类型 永远不存在的值 任何类型的字类型, 可以赋值给任何类型 但是任何类型都不可赋值给 never, 包括 any function error(msg: string...如果变量定义的时候没有赋值, 默认是 any 类型 let x; // 可以赋值为任何类型的值 let x1 = '生生世世'; // x1会推论成sring类型, 不能给x1赋值为其他类型了 // x1...ts 类型的检查原则, 有一个东西看起来像鸭子、听起来像鸭子、叫起来也像鸭子,那么我们就可以认为他是鸭子 当一个类型 Y 可以被赋值给另一个类型 X 时, 就可以说类型 X 兼容类型 Y X 兼容 Y...可以通过配置 strictFunctionTypes 参数修复这个问题 枚举的兼容性 枚举类型与数字类型兼容,并且数字类型与枚举类型兼容 不同枚举类型之间是不兼容的 //数字可以赋给枚举 enum Colors
Roles[Roles['ADMIN']=1]="ADMIN" // Roles[Roles['USER']=2]="USER" // }(Roles||Roles={})) // any...类型 let value:any value='abc' value=123 value=false value=[1,2,'33'] let arr4:any[] // void(可以赋值为undefined...和null) const consoleText=(text)=>{ console.log(text); } let v:void v=undefined v=null // null 和undefined...(除了(never)是所有类型的子类型,可以赋值给任何类型) let u:undefined u=null let n:null n=undefined // never类型(永远没有结果的函数) let...message:string):never=>{ throw new Error(message) } errorFunc=()=>{ while(true){} } // obj类型(内存中地址的引用
通俗来说也就是多的可以赋值给少的,上述代码因为 a 的类型定义中完全包括 b 的类型定义,所以 a 类型完全是可以赋值给 b 类型,这被称为类型兼容性。...,刚刚才提到类型兼容性的原因 TS 允许不同类型进行互相赋值(只需要父/子集关系),那么明明 fn2 的参数包括了所有的 fn1 为什么会报错?...自然,这是安全的也是被 TS 允许赋值。 就比如上述函数的参数类型赋值就被称为逆变,参数少(父)的可以赋给参数多(子)的那一个。...看起来和类型兼容性(多的可以赋给少的)相反,但是通过调用的角度来考虑的话恰恰满足多的可以赋给少的兼容性原则。 上述这种函数之间互相赋值,他们的参数类型兼容性是典型的逆变。...string|number|boolean 赋给 string 类型 这里,函数类型赋值兼容时函数的返回值就是典型的协变场景,我们可以看到 fn1 函数返回值类型规定为 string,fn2 返回值类型规定为
{ name: string; } interface Cat extends Animal { run(): void; } 那么也不难理解为什么 Cat 类型的 tom 可以赋值给...Animal 类型的 animal 了——就像面向对象编程中我们可以将子类的实例赋值给类型为父类的变量。...,将 tom 声明为 Cat,然后再将 any 类型的 getCacheData('tom') 赋值给 Cat 类型的 tom。...animal 断言为 Cat 赋值给 tom。...则会报错,不允许将 animal 赋值为 Cat 类型的 tom。 这很容易理解,Animal 可以看作是 Cat 的父类,当然不能将父类的实例赋值给类型为子类的变量。
因此赋值时变量的形状必须和接口的形状保持一致 二、可选属性 可选属性是指该属性可以不存在,当我们希望不要完全匹配一个形状,可以用可选属性: interface Person { name: string...: 25, gender: 'male' }; 四、只读属性 有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性: interface Person...上例中,使用 readonly 定义的属性 id 初始化后又被赋值,所以报错 注意,只读的约束存在于第一次给对象赋值的时候,而非第一次给只读属性赋值的时候: interface Person {...上例中,报错信息有两处: 1、在对 faker 进行赋值的时候,没有给 id 赋值 2、在给 faker.id 赋值的时候,由于它是只读属性,所以报错了 五、联合类型和接口 以下实例演示了如何在接口中使用联合类型...IParent2 { v2:number } interface Child extends IParent1, IParent2 { } let faker:Child = { v1
考虑使用 jquery 的用例,你可以非常简单快速的为它创建一个定义: declare var $: any; 有时候,你可能想给某些变量一些明确的定义(如:jquery),并且你会在类型声明空间中使用它...event as HTMLElement; // Error: 'Event' 和 'HTMLElement' 中的任何一个都不能赋值给另外一个 } 如果你仍然想使用那个类型,你可以使用双重断言。...类型被允许 你可以随意调用泛型参数,当你使用简单的泛型时,泛型常用 T、U、V 表示。...: let foo: never = 123; // Error: number 类型不能赋值给 never 类型 // ok, 做为函数返回类型的 never let bar: never = ((...当一个函数没有返回值时,它返回了一个 void 类型,但是,当一个函数根本就没有返回值时(或者总是抛出错误),它返回了一个 never,void 指可以被赋值的类型(在 strictNullChecking
如上图,可以说Ts是Js的超集。 定义类型的好处 如下,我想求和a和b,但是又错误的给a赋值了'sk',那么c的值就成了拼接字符串的结果。...这种情况是 显示的any let no_use : any 而在定义变量时,不赋值,就是 隐式any 。Ts检测到没有指定类型,然后给添加类型为any。 let d; !!!!! 不建议使用。...let e:unknown e = 12 e ='sss' any和unknown的区别 如下,any类型的值可以赋值给字符串。...any可以霍霍别人儿 let no_use:any let str:string str = no_use 而 把unknown赋值给别的类型 就会报错。...let str:string let e:unknown e ='sss' str = e unknown类型实际上是一个类型安全的any,unknown类型的变量不能赋值给其他变量 unknown类型赋值给
但也要意识到,如果你预先知道要将一个对象赋给一个变量名,相比a - b 的盲操作,就可能会更高效。...(译注:作者关于二元运算的文章,译文在此) 最终无论用了哪种方法,返回值都会被赋值给 a。...通过传入二元算术运算函数,并做一些自省(以及处理可能发生的 TypeError),它可以被漂亮地归纳成: def _create_binary_inplace_op(binary_op: _BinaryOp...-= 支持 _create_binary_inplace_op(__ sub__),且可以推断出其它内容:函数名、调用什么 __i*__ 函数,以及当二元算术运算出问题时,该调用哪个可调用对象。...*w, PyObject *z) { if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_inplace_power
为什么要学习 TypeScript ? 3. 安装 TypeScript 4. 原始数据类型和 any 类型 5. 数组和元组(tuple) 6. Interface 接口 7....---- 程序更容易理解 ts 可以约定函数或方法输入输出的参数类型,外部条件等 效率更高 在不同的代码块和定义中进行跳转、代码补全、接口提示 更少的错误 编译期间能够发现大部分错误,杜绝一些比较常见的错误...另外一种是 Object 注意: undefined、null 是所有类型的子类型,所以下面写法是正确的 let age: number = undefined 顶级类型: any,可以接收所有数据类型的数据...函数中声明数据类型 ---- 普通的声明函数,函数的结果返回 number 类型 /** 函数表达式声明的函数返回的是一个函数类型 const add = (x: number, y: number,...,没有指定数据类型,ts 会自动推测出一个类型,如下图: 因为 ts 已经将变量 x 的类型推断为 number,那么当我们给变量 x 赋值一个 string 类型的数据则会提示错误 9.
2、如果你跟着敲了代码,并且有其它的思想,你会发现当你预设了一个类型给到变量,那么后期再赋值时,只能赋值相同类型的值给到这个变量。例如: str = 123;这时候编辑器会报错。.../ 给元组错误赋值 x = [10, 'hello']; // Error 枚举,使用枚举类型可以为一组数值赋予友好的名字。...就是说你可以把 null和undefined赋值给number类型的变量。...Never类型表示的是那些永不存在的值的类型 1、never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 2、never类型是任何类型的子类型,也可以赋值给任何类型...;any不可以赋值给never。
}编辑器中会直接报错,我们可以在变量声明的时候就告诉编辑器该属性一定会被赋值,即在变量名后面加个!...any为什么会有这种需求呢?...比如以下案例:我们知道obj一定是有值的,请求接口后赋值给obj,所以一定是有值的,但是我们直接赋值,就会报错const obj = {};obj.name = 'zhangsan';obj.age =...19;const obj:Object = {};(obj).name = 'zhangsan';(obj).age = 19;(4)调用函数时将参数和返回值断言成精确的值function...func(val:any):any{ return 1}func(1)调用函数时我们改成以下所示,这样方便我们维护代码,约束了传参和函数返回值,不能any走天下。
let a: void = null; let b: void = undefined; 4.1 any、void、never、unknown 的区别 4.1.1 any ts 检测弱,兼容性问题解决方案...let a; // a: any a = 1; let a = 1; //a: number 4.1.2 void void应当仅仅用于函数声明,即没有明确返回值的函数,应该被声明为void类型。...4.1.3 never never用于函数返回值时,表示函数有抛出异常,没有正常执行到底。用于变量声明,无法为其赋予任何值! never是所有类型的子类型并且可以赋值给所有类型。...没有类型是never的子类型或能赋值给never(never类型本身除外)。...never: T; 4.1.4 unknown unknown相对于any,任意类型都可以赋值给unknow,但是不可对其进行任何访问操作(仅仅为类型安全,any操作访问也安全) let a:
也就是说 undefined 类型的变量,可以赋值给所有类型的变量,包括 void 类型: let num: number = undefined; let u: undefined; let str...: string = u; let vo: void= u; // 编译通过 而 void 类型的变量不能赋值给其他类型的变量,只能赋值给 void 类型: let u: void; let num:...一个普通类型,在赋值过程中是不被允许改变类型的,any 类型,允许被赋值为任意类型。...例二:只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值时: interface Person { readonly id: number; name: string;...: number; [propName: string]: any; } let p2: Person = { // 第一次给对象赋值 name: 'Tom', gender
需要注意的是,number是类型,而Number是构造函数。 当函数没有返回值时,返回类型就是void。只有null和undefined可以赋给void 。...never 类型表示的是那些永不存在的值的类型,never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是 never的子类型或可以赋值给 never类型(除了never本身之外)。...Person) {} if (arg.name === 'chuck') {} if (typeof name === 'string') {} 类型兼容性 「类型兼容性」用于确定一个类型是否能赋值给其他类型...P : T; 如果 T 能赋值给 (param: infer P) => any,则结果是(param: infer P) => any类型中的参数 P,否则返回为 T,infer P表示待推断的函数参数...type ReturnType = T extends (...args: any[]) => infer P ? P : any; 如果T能赋值给函数类型,则返回函数的返回类型。
我们可以在变量声明的时候就告诉编辑器该属性一定会被赋值,即在变量名后面加个!符号let score!...any为什么会有这种需求呢?...比如以下案例:我们知道obj一定是有值的,请求接口后赋值给obj,所以一定是有值的,但是我们直接赋值,就会报错const obj = {};obj.name = 'zhangsan';obj.age =...19;我们可以改成这样就不会报错啦const obj:Object = {};(obj).name = 'zhangsan';(obj).age = 19;(4)调用函数时将参数和返回值断言成精确的值...function func(val:any):any{ return 1}func(1)调用函数时我们改成以下所示,这样方便我们维护代码,约束了传参和函数返回值,不能any走天下。
领取专属 10元无门槛券
手把手带您无忧上云