TypeScript 是 JavaScript 的一个扩展,增加了静态类型和类型检查。使用类型,你可以准确声明你的函数接收什么类型参数,返回什么类型结果。然后,你可以使用 TypeScript 类型检查器来捕获许多常见错误,例如拼写错误、忘记处理null
和undefined
等等。因为 TypeScript 代码看起来就像带类型的 JavaScript,所以你所知的关于 JavaScript 的所有东西仍然适用。当你需要的时候,你的类型可以被剥离出来,留下干净的、可读的、可运行的 JavaScript,可以在任何地方运行。你可以 访问我们的网站,了解更多关于 TypeScript 的信息。
开始使用 TypeScript 4.2,你可以 通过 NuGet 获取它,或者使用如下 npm 命令:
npm install typescript让我们来看看 TypeScript 4.2 有哪些功能!
-
更智能的类型别名保留
-
元组类型中的前导 / 中间剩余元组
-
针对
in
运算符的更严格的检查 -
--noPropertyAccessFromIndexSignature
-
abstract
构造符号 -
--explainFiles
标记 -
逻辑表达式中改进的未调用函数检查
-
解构变量可以显式标记为未使用
-
可选属性和字符串索引符号之间的宽松规则
-
声明缺失的帮助函数
-
破坏性更新
string | number | boolean
,你可以编写一个类型别名来避免反复重复。
type BasicPrimitive = number | string | boolean;TypeScript 在打印类型时,总是使用一套规则并猜测何时重用类型别名。以下面这段代码为例。
export type BasicPrimitive = number | string | boolean; export function doStuff(value: BasicPrimitive) { let x = value; return x; }如果我们在 Visual Studio、Visual Studio Code 或 TypeScript Playground 之类的编辑器中将鼠标悬停在
x
上时,我们将得到一个快速信息面板,显示其类型为BasicPrimitive
。同样,如果我们得到这个文件的声明文件输出(.d.ts
输出),TypeScript 会说,doStuff
返回BasicPrimitive
类型。然而,如果我们返回一个BasicPrimitive
或undefined
会怎么样呢?
export type BasicPrimitive = number | string | boolean; export function doStuff(value: BasicPrimitive) { if (Math.random() < 0.5) { return undefined; } return value; }我们可以看看 在 TypeScript playground 中 会发生什么。虽然我们可能希望 TypeScript 显示
doStuff
的类型为BasicPrimitive | undefined
,但它实际显示的是string | number | boolean | undefined
!为什么会这样?这与 TypeScript 如何在内部表示类型有关。当用一个或多个组合类型创建组合类型时,它总是将这些类型规范化为一个扁平的组合类型——但这样做会丢失信息。类型检查器必须从string | number | boolean | undefined
的所有组合类型中来看看哪种类型别名被使用了,即使这样,string | number | boolean
还可能有多个类型别名。
在 TypeScript 4.2 中,我们的内部结构更加智能。我们通过保留类型各部分最初是如何被编写和构建的,来跟踪类型是如何被构建的。我们还对类型别名与其它别名实例进行跟踪和区分!
能够根据你在代码中使用它们的方式来打印类型,意味着作为一名 TypeScript 用户,你可以避免显示一些非常庞大的类型,这通常会转化为更好的.d.ts
文件输出、异常信息和编辑器中的快速信息和符号帮助中的类型显示。这有助于让新手更容易上手 TypeScript。
有关更多信息,请查看第一个拉取请求,它改进了有关保留组合类型别名的各种用例,以及第二个拉取请求,它保留了间接别名。
https://github.com/microsoft/TypeScript/pull/42149
https://github.com/microsoft/TypeScript/pull/42284
元组类型中的前导 / 中间剩余元素在 TypeScript 中,元组类型用于对具有特定长度和元素类型的数组进行建模。// A tuple that stores a pair of numbers let a: [number, number] = [1, 2]; // A tuple that stores a string, a number, and a boolean let b: [string, number, boolean] = ["hello", 42, true];随着时间的推移,TypeScript 的元组类型变得越来越复杂,因为它们也被用于 JavaScript 中的参数列表之类的建模。因此,它们可以有可选元素和剩余元素,甚至可以有用于工具和可读性的标签。
// A tuple that has either one or two strings. let c: [string, string?] = ["hello"]; c = ["hello", "world"]; // A labeled tuple that has either one or two strings. let d: [first: string, second?: string] = ["hello"]; d = ["hello", "world"]; // A tuple with a *rest element* - holds at least 2 strings at the front, // and any number of booleans at the back. let e: [string, string, ...boolean[]]; e = ["hello", "world"]; e = ["hello", "world", false]; e = ["hello", "world", true, false, true];
在 TypeScript 4.2 中,剩余元素在如何使用方面进行了扩展。在以前的版本中,TypeScript 只允许...rest位于元组类型的最后位置。 然而,现在剩余元素可以出现在元组中的任何位置——只是有一些限制。
let foo: [...string[], number]; foo = [123]; foo = ["hello", 123]; foo = ["hello!", "hello!", "hello!", 123]; let bar: [boolean, ...string[], boolean]; bar = [true, false]; bar = [true, "some text", false]; bar = [true, "some", "separated", "text", false];唯一的限制是剩余元素可以放在一个元组的任何位置,只要它后面没有另一个可选元素或剩余元素。换句话说,每个元组只有一个剩余元素,并且剩余元素后面不能有可选元素。
interface Clown { /*...*/ } interface Joker { /*...*/ } let StealersWheel: [...Clown[], "me", ...Joker[]]; // ~~~~~~~~~~ Error! // A rest element cannot follow another rest element. let StringsAndMaybeBoolean: [...string[], boolean?]; // ~~~~~~~~ Error! // An optional element cannot follow a rest element.这些没有后缀的剩余元素可以被用来对采用任意数量的前导参数(后面跟几个固定参数)的函数进行建模。
declare function doStuff(...args: [...names: string[], shouldCapitalize: boolean]): void; doStuff(/*shouldCapitalize:*/ false) doStuff("fee", "fi", "fo", "fum", /*shouldCapitalize:*/ true);尽管 JavaScript 没有任何语法来为前导剩余参数建模,我们仍然可以通过使用一个带前导剩余元素的元组类型来声明
...args
剩余参数,来将doStuff
声明为一个接收前导参数的函数。这有助于对大量现有的 JavaScript 进行建模!
有关更多详细信息,请查看原始的拉取请求:
https://github.com/microsoft/TypeScript/pull/41544
针对in
操作符的更严格的检查在 JavaScript 中,在in
操作符右侧使用一个非对象类型是一个运行时错误。TypeScript 4.2 确保这可以在设计时发现这个错误。
"foo" in 42 // ~~ // error! The right-hand side of an 'in' expression must not be a primitive.这个检查在很大程度上是相当保守的,因此如果你收到了这个错误,那么代码中很可能有问题。非常感谢我们的外部贡献者 Jonas Hübotter 提交的 拉取请求!
引入新标志
当 TypeScript 第一次引入索引符号时,你只能使用“方括号包括的”元素获取语法(如person["name"]
)来获取它们声明的属性。
interface SomeType { /** This is an index signature. */ [propName: string]: any; } function doStuff(value: SomeType) { let x = value["someProperty"]; }在我们需要处理具有任意属性的对象的情况下,这会变得很麻烦。例如,假设一个 API,在一个属性名末尾多打了一个
s
字符是很常见的拼写错误。
interface Options { /** File patterns to be excluded. */ exclude?: string[]; /** * It handles any extra properties that we haven't declared as type 'any'. */ [x: string]: any; } function processOptions(opts: Options) { // Notice we're *intentionally* accessing `excludes`, not `exclude` if (opts.excludes) { console.error("The option `excludes` is not valid. Did you mean `exclude`?"); } }为了这些情况更简单,不久前,TypeScript 允许当一个类型有一个字符串索引符号时使用“点式”属性访问语法(如
person.name
)。这也使得现有 JavaScript 代码转换为 TypeScript 变得更容易。然而,放松限制也意味着错误拼写一个显式声明的属性变得容易得多。
function processOptions(opts: Options) { // ... // Notice we're *accidentally* accessing `excludes` this time. // Oops! Totally valid. for (const excludePattern of opts.excludes) { // ... } }在某些情况下,用户更愿意显式地选择索引符号——当点式属性访问与特定属性声明不对应时,他们更愿意收到错误消息。
这就是为什么 TypeScript 引入了一个新的标志,--noPropertyAccessFromIndexSignature
。在这种模式中,你将选择使用 TypeScript 的旧行为来发出错误。这个新的设置并不在strict
标志家族中,因为我们相信用户会发现它在特定代码库上比在其它代码库上更有用。
你可以通过阅读相应的拉取请求,来了解这个功能的更多细节:
https://github.com/microsoft/TypeScript/pull/40171/
我们也要向给我们发送这个拉取请求的 Wenlu Wang 致以衷心的感谢!
abstract
构造符号TypeScript 允许我们将一个类标记为 abstract。这告诉 TypeScript,这个类只会被继承,特别成员需要由任何实际创建的子类示例填充。
abstract class Shape { abstract getArea(): number; } // Error! Can't instantiate an abstract class. new Shape(); class Square extends Shape { #sideLength: number; constructor(sideLength: number) { this.#sideLength = sideLength; } getArea() { return this.#sideLength ** 2; } } // Works fine. new Square(42);为了确保在新建
abstract
类时始终应用此限制,你不能将abstract
类分配给任何需要构造符号的对象。
interface HasArea { getArea(): number; } // Error! Cannot assign an abstract constructor type to a non-abstract constructor type. let Ctor: new () => HasArea = Shape;如果我们打算像
new Ctor
那样运行代码,那么这样做是正确的,但是如果我们想要写一个Ctor
的子类,那么这样做就过于严格了。
functon makeSubclassWithArea(Ctor: new () => HasArea) { return class extends Ctor { getArea() { // ... } } } let MyShape = makeSubclassWithArea(Shape);对于
InstanceType
这样的内置助手类型,它也不能很好地生效。
// Error! // Type 'typeof Shape' does not satisfy the constraint 'new (...args: any) => any'. // Cannot assign an abstract constructor type to a non-abstract constructor type. type MyInstance = InstanceType<typeof Shape>;这就是 TypeScript 4.2 允许你在构造符号上指定一个
abstract
修饰符的原因。
interface HasArea { getArea(): number; } // Works! let Ctor: abstract new () => HasArea = Shape; // ^^^^^^^^将
abstract
修饰符添加到一个构造符号上,你可以传递abstract
构造器。它不会阻止你传入其它“具体的”类 / 构造函数——这实际上只是表示没有直接运行构造器的意图,因此传入任何类的类型都是安全的。这个特性允许我们以一种支持抽象类的方式写 mixin 工厂。例如,在下面的代码片段中,我们可以将 mixin 函数withStyles
与abstract
类SuperClass
一起使用。
abstract class SuperClass { abstract someMethod(): void; badda() {} } type AbstractConstructor<T> = abstract new (...args: any[]) => T function withStyles<T extends AbstractConstructor<object>>(Ctor: T) { abstract class StyledClass extends Ctor { getStyles() { // ... } } return StyledClass; } class SubClass extends withStyles(SuperClass) { someMethod() { this.someMethod() } }
请注意,withStyles演示的是一个特定的规则,其中类(例如StyledClass)继承了一个泛型值,并被一个抽象构造器(例如Ctor)限定,必须被声明为abstract。这是因为无法知道是否传入了具有更多抽象成员的类,因此不可能知道子类是否实现了所有的抽象成员。 你可以通过这个拉取请求阅读更多关于抽象构造符号的信息: https://github.com/microsoft/TypeScript/pull/36392 利用--explainFiles理解你的项目结构 对于 TypeScript 用户来说,一个出人意料的常见场景是问“为什么 TypeScript 包含这个文件?”。推断程序的文件是一个复杂的过程,因此有很多原因可以解释为什么要使用lib.d.ts的特定组合,为什么要包括node_modules中的某些文件,以及要包含某些文件金骨干我们认为指定exclude会将它们排除在外。 这就是 TypeScript 现在 提供explainFiles标志的原因。
tsc --explainFiles当使用此选项时,TypeScript 编译器将给出一些非常详细的输出,说明文件为什么会出现在程序中。为了更容易读取,你可以将输出转到一个文件,或者通过管道将其传输到一个可以轻松查看它的程序。
# Forward output to a text file tsc --explainFiles > expanation.txt # Pipe output to a utility program like `less`, or an editor like VS Code tsc --explainFiles | less tsc --explainFiles | code -通常,输出将首先列出包含
lib.d.ts
文件的原因,然后列出本地文件的原因,然后列出node_modules
文件的原因。
TS_Compiler_Directory/4.2.2/lib/lib.es5.d.ts Library referenced via 'es5' from file 'TS_Compiler_Directory/4.2.2/lib/lib.es2015.d.ts' TS_Compiler_Directory/4.2.2/lib/lib.es2015.d.ts Library referenced via 'es2015' from file 'TS_Compiler_Directory/4.2.2/lib/lib.es2016.d.ts' TS_Compiler_Directory/4.2.2/lib/lib.es2016.d.ts Library referenced via 'es2016' from file 'TS_Compiler_Directory/4.2.2/lib/lib.es2017.d.ts' TS_Compiler_Directory/4.2.2/lib/lib.es2017.d.ts Library referenced via 'es2017' from file 'TS_Compiler_Directory/4.2.2/lib/lib.es2018.d.ts' TS_Compiler_Directory/4.2.2/lib/lib.es2018.d.ts Library referenced via 'es2018' from file 'TS_Compiler_Directory/4.2.2/lib/lib.es2019.d.ts' TS_Compiler_Directory/4.2.2/lib/lib.es2019.d.ts Library referenced via 'es2019' from file 'TS_Compiler_Directory/4.2.2/lib/lib.es2020.d.ts' TS_Compiler_Directory/4.2.2/lib/lib.es2020.d.ts Library referenced via 'es2020' from file 'TS_Compiler_Directory/4.2.2/lib/lib.esnext.d.ts' TS_Compiler_Directory/4.2.2/lib/lib.esnext.d.ts Library 'lib.esnext.d.ts' specified in compilerOptions ... More Library References... foo.ts Matched by include pattern '**/*' in 'tsconfig.json'现在,我们对输出格式没有任何保证——它可能会随着时间变化。在这一点上,如果你有任何建议,我们有兴趣改进这种格式!有关更多信息,请查看原始的拉取请求:
https://github.com/microsoft/TypeScript/pull/40011
逻辑表达式中改进的未调用函数检查由于 Alex Tarasyuk 的进一步改进,TypeScript 的未调用函数检查现在可以用于&&
和||
表达式。在--strictNullChecks
模式下,下列代码现在会报错。
function shouldDisplayElement(element: Element) { // ... return true; } function getVisibleItems(elements: Element[]) { return elements.filter(e => shouldDisplayElement && e.children.length) // ~~~~~~~~~~~~~~~~~~~~ // This condition will always return true since the function is always defined. // Did you mean to call it instead. }获取更多细节,请查看这里的拉取请求:
https://github.com/microsoft/TypeScript/issues/40197
解构变量可以显式标记为未使用由于 Alex Tarasyuk 的另一个拉取请求,你现在可以通过在解构变量前增加一个下划线(_
字符),来将解构变量标记为未使用。
let [_first, second] = getValues();以前,如果
_first
以后从未使用过,TypeScript 会报一个noUnusedLocals
错误。现在,TypeScript 将意识到,_first
是故意用下划线命名的,因为没有使用它的意图。
获取更多细节,请查看完整的更改:
https://github.com/microsoft/TypeScript/pull/41378
可选属性和字符串索引符号之间的宽松规则字符串索引符号一种类似字典的对象,你可以使用其中的任意键进行访问:const movieWatchCount: { [key: string]: number } = {}; function watchMovie(title: string) { movieWatchCount[title] = (movieWatchCount[title] ?? 0) + 1; }当然,对于字典中还没有任何电影标题,
movieWatchCount[title]
会报undefined
(TypeScript 4.1 增加了--noUncheckedIndexedAccess
选项,以便在读取这样的索引符号时包括undefined
)。尽管很明显movieWatchCount
中肯定有一些字符串不存在,但是由于undefined
的存在,TypeScript 的早期版本认为对象的可选属性不能用兼容索引符号赋值。
type WesAndersonWatchCount = { "Fantastic Mr. Fox"?: number; "The Royal Tenenbaums"?: number; "Moonrise Kingdom"?: number; "The Grand Budapest Hotel"?: number; }; declare const wesAndersonWatchCount: WesAndersonWatchCount; const movieWatchCount: { [key: string]: number } = wesAndersonWatchCount; // ~~~~~~~~~~~~~~~ error! // Type 'WesAndersonWatchCount' is not assignable to type '{ [key: string]: number; }'. // Property '"Fantastic Mr. Fox"' is incompatible with index signature. // Type 'number | undefined' is not assignable to type 'number'. // Type 'undefined' is not assignable to type 'number'. (2322)TypeScript 4.2 允许这种赋值。然而,它不允许对类型中
undefined
的非可选属性进行赋值,也不允许将undefined
写到特定键:
type BatmanWatchCount = { "Batman Begins": number | undefined; "The Dark Knight": number | undefined; "The Dark Knight Rises": number | undefined; }; declare const batmanWatchCount: BatmanWatchCount; // Still an error in TypeScript 4.2. // `undefined` is only ignored when properties are marked optional. const movieWatchCount: { [key: string]: number } = batmanWatchCount; // Still an error in TypeScript 4.2. // Index signatures don't implicitly allow explicit `undefined`. movieWatchCount["It's the Great Pumpkin, Charlie Brown"] = undefined;新规则也不适用于数字索引符号,因为它们被假定为类似数组且密集的:
declare let sortOfArrayish: { [key: number]: string }; declare let numberKeys: { 42?: string }; // Error! Type '{ 42?: string | undefined; }' is not assignable to type '{ [key: number]: string; }'. sortOfArrayish = numberKeys;你可以通过阅读原始拉取请求来更好地了解这个变化:
https://github.com/microsoft/TypeScript/pull/41921
声明缺失的帮助函数由于来自 Alexander Tarasyuk 的一个社区拉取请求,我们现在有了一个基于调用站点声明新函数和方法的快速修复!
破坏性变更
我们总是尽量减少发布中的破坏性变更。TypeScript 4.2 包含一些破坏性变更,但我们认为它们在升级中是可控的。
lib.d.ts
更新
与每个 TypeScript 版本一样,lib.d.ts
的声明(尤其是针对 web 上下文生成的声明)已经发生了变化。有各种变化,而Intl
和ResizeObserver
的变化可能是最具有破坏性的。
noImplicitAny
错误适用于松散的yield
表达式当一个yield
表达式的值被捕获,但是 TypeScript 不能立即识别你想要它接收的类型(即yield
表达式的上下文类型不明确)时,TypeScript 现在会发出一个隐式的any
错误。
function* g1() { const value = yield 1; // ~~~~~~~ // Error! // 'yield' expression implicitly results in an 'any' type // because its containing generator lacks a return-type annotation. } function* g2() { // No error. // The result of `yield 1` is unused. yield 1; } function* g3() { // No error. // `yield 1` is contextually typed by 'string'. const value: string = yield 1; } function* g3(): Generator<number, void, string> { // No error. // TypeScript can figure out the type of `yield 1` // from the explicit return type of `g3`. const value = yield 1; }请参见相应更改中的更多细节:
https://github.com/microsoft/TypeScript/pull/41348
扩展的未调用的函数检查如上所述,在使用--strictNullChecks
时,未调用的函数检查现在将在&&
和||
表达式中一致地操作。这可能是新中断的来源,但通常表示现有代码中存在逻辑错误。
f<T>(100)TypeScript 会将它解析为如下 JavaScript:
(f < T) > (100)如果你正利用 TypeScript 的 API 来解析 JavaScript 文件中的类型构造(在尝试解析 Flow 文件时会发生),这可能会对你有所影响。
in
运算符不在允许在后边出现原始类型如前所述,在in
运算符右边使用原始类型是一个错误,而 TypeScript 4.2 对这类代码更严格。
"foo" in 42 // ~~ // error! The right-hand side of an 'in' expression must not be a primitive.有关检查内容的更多细节请查看拉取请求:
https://github.com/microsoft/TypeScript/pull/41928
spreads 的元组大小限制元组类型可以通过在 TypeScript 中使用任何类型的 spread 语法(...
)来生成。
// Tuple types with spread elements type NumStr = [number, string]; type NumStrNumStr = [...NumStr, ...NumStr]; // Array spread expressions const numStr = [123, "hello"] as const; const numStrNumStr = [...numStr, ...numStr] as const;有时,这些元素类型可能会意外地增长到非常大,这会导致类型检查花费很长时间。TypeScript 没有让类型检查进程挂起(在编辑器场景中尤其糟糕),而是设置了一个限制器来避免执行所有这些检查。
你可以查看这个拉取请求来获取更多细节:
https://github.com/microsoft/TypeScript/pull/42448
.d.ts
扩展不能用于导入路径在 TypeScript 4.2 中,导入路径的扩展名中包含.d.ts
现在是一个错误。
// must be changed something like // - "./foo" // - "./foo.js" import { Foo } from "./foo.d.ts";相反,导入路径应该反映加载程序在运行时将执行的操作。可以使用以下任何一种导入。
import { Foo } from "./foo"; import { Foo } from "./foo.js"; import { Foo } from "./foo/index.js";还原模板字面推断
此更改从 TypeScript 4.2 beta 中删除了一个功能。如果你还没有升级到上一个稳定版本,你不会受到影响,但你仍然可能对变更感兴趣。
TypeScript 4.2 的 beta 版本包含了对模板字符串推断的更改。在这个变更中,模板字符串字面要么被赋予模板字符串类型,要么被简化为多个字符串语义类型。当赋值给可变变量时,这些类型将被放宽为string
。
declare const yourName: string; // 'bar' is constant. // It has type '`hello ${string}`'. const bar = `hello ${yourName}`; // 'baz' is mutable. // It has type 'string'. let baz = `hello ${yourName}`;这和字符串字面推断的工作方式类似。
// 'bar' has type '"hello"'. const bar = "hello"; // 'baz' has type 'string'. let baz = "hello";因此,我们认为使模板字符串表达式具有模板字符串类型是“一致的”;然而,从我们的所见所闻来看,这并不总是可取的。作为回应,我们恢复了这个特性(以及潜在的破坏性变更)。如果你确实希望给模板字符串表达式指定类似字面的类型,你可以在其末尾添加
as const
。
declare const yourName: string; // 'bar' has type '`hello ${string}`'. const bar = `hello ${yourName}` as const; // ^^^^^^^^ // 'baz' has type 'string'. const baz = `hello ${yourName}`;
visitNode
中 TypeScript 的lift
回调使用不同的类型TypeScript 有一个visitNode
函数,接收lift
函数。lift
现在需要一个readonly Node[]
而不是一个NodeArray<Node>
。这在技术上是一个破坏性变化,你可以通过下方链接了解更多信息:
https://github.com/microsoft/TypeScript/pull/42000
下一步?虽然 4.2 刚刚发布,我们的团队已经在努力开发 TypeScript 4.3。你可以查看 TypeScript 4.3 迭代计划:
https://github.com/microsoft/TypeScript/issues/42762
和我们的滚动特性路线图:
https://github.com/Microsoft/TypeScript/wiki/Roadmap
你还可以使用 TypeScript 每日发行版(nightly release)以及我们的 nightly Visual Studio 代码扩展来保持最新。每日发行版往往是相当稳定的,早期反馈是被鼓励和赞赏的!
但是我们希望大部分用户现在使用 TypeScript 4.2;因此,如果你正在使用 TypeScript 4.2,我们希望这个版本容易上手,并使你的工作效率更高。如果没有,我们希望听到你的事例!我们想要保证 TypeScript 在编码中给您带来了乐趣,我希望我们已经做到了这一点。
编码快乐!
– Daniel Rosenwasser 和 TypeScript 团队
作者介绍Daniel 技术经理,专注于 TypeScript。
延伸阅读
https://devblogs.microsoft.com/typescript/announcing-typescript-4-2/
以上文章摘选自---前端之巅
相关推荐
对于那些对TypeScript有深入研究的开发者,本书还提供了关于TypeScript的最新版本变更和可能的破坏性变化的信息,帮助开发者跟上TypeScript的发展步伐。 总之,《TypeScript手册》是一本全方位的TypeScript宝典,...
TypeScript是JavaScript的一个超集,它添加了静态类型和其他高级特性,使得大型项目更具可维护性和可靠性。 在"adventofcode-2020"中,每个挑战通常分为两个部分,第一天的问题简单引入概念,第二天则会增加复杂度...
基于Maxwell设计的经典280W 4025RPM高效率科尔摩根12极39槽TBM无框力矩电机:生产与学习双重应用案例,基于Maxwell设计的经典280W高转速科尔摩根TBM无框力矩电机:7615系列案例解析与应用实践,基于maxwwell设计的经典280W,4025RPM 内转子 科尔摩根 12极39槽 TBM无框力矩电机,7615系列。 该案例可用于生产,或者学习用,(157) ,maxwell设计; 280W; 4025RPM内转子; 科尔摩根; 12极39槽TBM无框力矩电机; 7615系列; 生产/学习用。,基于Maxwell设计,高功率280W 12极39槽TBM无框力矩电机:生产与学习双用途案例
基于碳交易的微网优化模型的Matlab设计与实现策略分析,基于碳交易的微网优化模型的Matlab设计与实现探讨,考虑碳交易的微网优化模型matlab ,考虑碳交易; 微网优化模型; MATLAB;,基于Matlab的碳交易微网优化模型研究
二级2025模拟试题(答案版)
OpenCV是一个功能强大的计算机视觉库,它提供了多种工具和算法来处理图像和视频数据。在C++中,OpenCV可以用于实现基础的人脸识别功能,包括从摄像头、图片和视频中识别人脸,以及通过PCA(主成分分析)提取图像轮廓。以下是对本资源大体的介绍: 1. 从摄像头中识别人脸:通过使用OpenCV的Haar特征分类器,我们可以实时从摄像头捕获的视频流中检测人脸。这个过程涉及到将视频帧转换为灰度图像,然后使用预训练的Haar级联分类器来识别人脸区域。 2. 从视频中识别出所有人脸和人眼:在视频流中,除了检测人脸,我们还可以进一步识别人眼。这通常涉及到使用额外的Haar级联分类器来定位人眼区域,从而实现对人脸特征的更细致分析。 3. 从图片中检测出人脸:对于静态图片,OpenCV同样能够检测人脸。通过加载图片,转换为灰度图,然后应用Haar级联分类器,我们可以在图片中标记出人脸的位置。 4. PCA提取图像轮廓:PCA是一种统计方法,用于分析和解释数据中的模式。在图像处理中,PCA可以用来提取图像的主要轮廓特征,这对于人脸识别技术中的面部特征提取尤
麻雀搜索算法(SSA)自适应t分布改进版:卓越性能与优化代码注释,适合深度学习。,自适应t分布改进麻雀搜索算法(TSSA)——卓越的学习样本,优化效果出众,麻雀搜索算法(SSA)改进——采用自适应t分布改进麻雀位置(TSSA),优化后明显要优于基础SSA(代码基本每一步都有注释,代码质量极高,非常适合学习) ,TSSA(自适应t分布麻雀位置算法);注释详尽;高质量代码;适合学习;算法改进结果优异;TSSA相比基础SSA。,自适应T分布优化麻雀搜索算法:代码详解与学习首选(TSSA改进版)
锂电池主动均衡Simulink仿真研究:多种均衡策略与电路架构的深度探讨,锂电池主动均衡与多种均衡策略的Simulink仿真研究:buckboost拓扑及多层次电路分析,锂电池主动均衡simulink仿真 四节电池 基于buckboost(升降压)拓扑 (还有传统电感均衡+开关电容均衡+双向反激均衡+双层准谐振均衡+环形均衡器+cuk+耦合电感)被动均衡电阻式均衡 、分层架构式均衡以及分层式电路均衡,多层次电路,充放电。 ,核心关键词: 锂电池; 主动均衡; Simulink仿真; 四节电池; BuckBoost拓扑; 传统电感均衡; 开关电容均衡; 双向反激均衡; 双层准谐振均衡; 环形均衡器; CUK均衡; 耦合电感均衡; 被动均衡; 电阻式均衡; 分层架构式均衡; 多层次电路; 充放电。,锂电池均衡策略研究:Simulink仿真下的多拓扑主动与被动均衡技术
S7-1500和分布式外围系统ET200MP模块数据
内置式永磁同步电机无位置传感器模型:基于滑膜观测器和MTPA技术的深度探究,内置式永磁同步电机基于滑膜观测器和MTPA的无位置传感器模型研究,基于滑膜观测器和MTPA的内置式永磁同步电机无位置传感器模型 ,基于滑膜观测器;MTPA;内置式永磁同步电机;无位置传感器模型,基于滑膜观测与MTPA算法的永磁同步电机无位置传感器模型
centos7操作系统下安装docker,及docker常用命令、在docker中运行nginx示例,包括 1.设置yum的仓库 2.安装 Docker Engine-Community 3.docker使用 4.查看docker进程是否启动成功 5.docker常用命令及nginx示例 6.常见问题
给曙光服务器安装windows2012r2时候找不到磁盘,问厂家工程师要的raid卡驱动,内含主流大多数品牌raid卡驱动
数学建模相关主题资源2
西门子四轴卧式加工中心后处理系统:828D至840D支持,四轴联动制造解决方案,图档处理与试看程序一应俱全。,西门子四轴卧加后处理系统:支持828D至840D系统,四轴联动高精度制造解决方案,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与经典文献参考,MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与文献参考,MATLAB代码:基于列约束生成法CCG的两阶段问题求解 关键词:两阶段鲁棒 列约束生成法 CCG算法 参考文档:《Solving two-stage robust optimization problems using a column-and-constraint generation method》 仿真平台:MATLAB YALMIP+CPLEX 主要内容:代码构建了两阶段鲁棒优化模型,并用文档中的相对简单的算例,进行CCG算法的验证,此篇文献是CCG算法或者列约束生成算法的入门级文献,其经典程度不言而喻,几乎每个搞CCG的两阶段鲁棒的人都绕不过此篇文献 ,两阶段鲁棒;列约束生成法;CCG算法;MATLAB;YALMIP+CPLEX;入门级文献。,MATLAB代码实现:基于两阶段鲁棒与列约束生成法CCG的算法验证研究
“生热研究的全面解读:探究参数已配置的Comsol模型中的18650圆柱锂电池表现”,探究已配置参数的COMSOL模型下的锂电池生热现象:18650圆柱锂电池模拟分析,出一个18650圆柱锂电池comsol模型 参数已配置,生热研究 ,出模型; 18650圆柱锂电池; comsol模型; 参数配置; 生热研究,构建18650电池的COMSOL热研究模型
移动端多端运行的知识付费管理系统源码,TP6+Layui+MySQL后端支持,功能丰富,涵盖直播、点播、管理全功能及礼物互动,基于UniApp跨平台开发的移动端知识付费管理系统源码:多端互通、全功能齐备、后端采用TP6与PHP及Layui前端,搭载MySQL数据库与直播、点播、管理、礼物等功能的强大整合。,知识付费管理系统源码,移动端uniApp开发,app h5 小程序一套代码多端运行,后端php(tp6)+layui+MySQL,功能齐全,直播,点播,管理,礼物等等功能应有尽有 ,知识付费;管理系统源码;移动端uniApp开发;多端运行;后端php(tp6);layui;MySQL;直播点播;管理功能;礼物功能,知识付费管理平台:全功能多端运行系统源码(PHP+Layui+MySQL)
基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,Python+Django+Mysql个性化图书推荐系统 图书在线推荐系统 基于用户、项目、内容的协同过滤推荐算法。 帮远程安装部署 一、项目简介 1、开发工具和实现技术 Python3.8,Django4,mysql8,navicat数据库管理工具,html页面,javascript脚本,jquery脚本,bootstrap前端框架,layer弹窗组件、webuploader文件上传组件等。 2、项目功能 前台用户包含:注册、登录、注销、浏览图书、搜索图书、信息修改、密码修改、兴趣喜好标签、图书评分、图书收藏、图书评论、热点推荐、个性化推荐图书等功能; 后台管理员包含:用户管理、图书管理、图书类型管理、评分管理、收藏管理、评论管理、兴趣喜好标签管理、权限管理等。 个性化推荐功能: 无论是否登录,在前台首页展示热点推荐(根据图书被收藏数量降序推荐)。 登录用户,在前台首页展示个性化推荐
STM32企业级锅炉控制器源码分享:真实项目经验,带注释完整源码助你快速掌握实战经验,STM32企业级锅炉控制器源码:真实项目经验,完整注释,助力初学者快速上手,stm32真实企业项目源码 项目要求与网上搜的那些开发板的例程完全不在一个级别,也不是那些凑合性质的项目可以比拟的。 项目是企业级产品的要求开发的,能够让初学者了解真实的企业项目是怎么样的,增加工作经验 企业真实项目网上稀缺,完整源码带注释,适合没有参与工作或者刚学stm32的增加工作经验, 这是一个锅炉的控制器,有流程图和程序协议的介绍。 ,stm32源码;企业级项目;工作经验;锅炉控制器;流程图;程序协议,基于STM32的真实企业级锅炉控制器项目源码
整车性能目标书:涵盖燃油车、混动车及纯电动车型的十六个性能模块目标定义模板与集成开发指南,整车性能目标书:涵盖燃油车、混动车及纯电动车型的十六个性能模块目标定义模板与集成开发指南,整车性能目标书,汽车性能目标书,十六个性能模块目标定义模板,包含燃油车、混动车型及纯电动车型。 对于整车性能的集成开发具有较高的参考价值 ,整车性能目标书;汽车性能目标书;性能模块目标定义模板;燃油车;混动车型;纯电动车型;集成开发;参考价值,《汽车性能模块化目标书:燃油车、混动车及纯电动车的集成开发参考》