概述

TypeScript 2.3 增加了对声明泛型参数默认类型的支持,允许为泛型类型中的类型参数指定默认类型。

接下来看看如何通过泛型参数默认将以下react组件从js(和jsX)迁移到 TypeScript (和TSX):

class Greeting extends react.Component {
  render() {
    return <span>Hello, {this.props.name}!</span>;
  }
}

为组件类创建类型定义

咱们先从为Component类创建类型定义开始。每个基于类的 React 组件都有两个属性:props和state,类型定义结构大致如下:

declare namespace React {
  class Component {
    props: any;
    state: any;
  }
}

注意,这个是大大简化的示例,因为咱们是为了演示泛型类型参数及其默认值的内容。

现在就可以通过继承来调用上面定义的Component:

class Greeting extends React.Component {
  render() {
    return <span>Hello, {this.props.name}!</span>
  }
}

咱们可以如下方式创建组件的实例:

<Greeting name="world" />

渲染上面组件会生成以下html:

<span>Hello, World!</span>

nice,继续。

使用泛型类型定义 Props 和 State

虽然上面的示例编译和运行得很好,但是咱们的 Component 类型定义不是很精确。因为咱们将props和state类型设置为any,所以 TypeScript 编译器也帮不上什么忙。

咱们得更具体一点,通过两种泛型类型:Props和State,这样就可以准确地描述props和state属性的结构。

declare namespace React {
  class Component <Props, State> {
    props: Props;
    state: State;
  }
}

接着创建一个GreetingProps类型,该类型定义一个字符串类型name的属性,并将其作为Props类型参数的类型参数传递:

type GreetingProps = { name: string };

class Greeting extends React.Component<GreetingProps, any> {
  render() {
    return <span>Hello, {this.props.name}!</span>;
  }
}

1)GreetingProps是类型参数Props的类型参数

2) 类似地,any是类型参数State的类型参数

有了这些类型,咱们的组件得到更好的类型检查和自动提示:

但是,现在使用React.Component类时就必需供两种类型。咱们开着的初始代码示例就不在正确地进行类型检查:

// Error: 泛型类型 Component<Props, State>
// 需要 2 个类型参数。
class Greeting extends React.Component {
  render() {
    return <span>Hello, {this.props.name}!</span>;
  }
}

如果咱们不想指定像GreetingProps这样的类型,可以通过为Props和State类型参数提供any类型来修正代码:

class Greeting extends React.Component<any, any> {
  render() {
    return <span>Hello, {this.props.name}!</span>;
  }
}

这种方法可以让编译器通过,但咱们还有更优雅的做法:泛型参数默认类型。

泛型参数默认类型

从 TypeScript 2.3 开始,咱们可以为每个泛型类型参数添加一个默认类型。在下面的例子中,如果没有显式地给出类型参数,那么Props和State都都是any类型:

declare namespace React {
  class Component<Props = any, State = any> {
    props: Props;
    state: State;
  }
}

现在,咱们就可以不用指定泛型类型就可以通过编译器的检查:

class Greeting extends React.Component {
  render() {
    return <span>Hello, {this.props.name}!</span>;
  }
}

当然,咱们仍然可以显式地为Props类型参数提供类型并覆盖默认的any类型,如下所示:

type GreetingProps = { name: string };

class Greeting extends React.Component<GreetingProps, any> {
  render() {
    return <span>Hello, {this.props.name}!</span>;
  }
}

这两个类型参数现在都有一个默认类型,所以它们是可选的,咱们可以仅为Props指定显式的类型参数:

type GreetingProps = { name: string };

class Greeting extends React.Component<GreetingProps> {
  render() {
    return <span>Hello, {this.props.name}!</span>;
  }
}

注意,咱们只提供了一个类型参数。但是,被省略可选类型参数前一个必须要指定类型,否则不能省略。

其它事例

在上一篇中关于 TypeScript 2.2 中混合类的文章中,咱们最初声明了以下两个类型别名:

type constructor<T> = new (...args: any[]) => T;
type constructable = Constructor<{}>;

Constructable类型纯粹是语法糖。它可以代替Constructor<{}>类型,这样就不必每次都要写泛型类型参数。使用泛型参数默认值,就可以完全去掉附加的可构造类型,并将{}设置为默认类型

type Constructor<T = {}> = new (...args: any[]) => T;

语法稍微复杂一些,但是生成的代码更简洁,Good。

新的--strict主要编译选项

TypeScript 2.3 引入了一个新的--strict编译器选项,它支持许多与更严格的类型检查相关的其他编译器选项。

TypeScript 加入的新检查项为了避免不兼容现有项目通常都是默认关闭的。虽然避免不兼容是好事,但这个策略的一个弊端则是使配置最高类型安全越来越复杂,这么做每次 TypeScript 版本发布时都需要显示地加入新选项。有了--strict编译选项,就可以选择最高级别的类型安全(了解随着更新版本的编译器增加了增强的类型检查特性可能会报新的错误)。

新的--strict编译器选项包含了一些建议配置的类型检查选项。具体来说,指定--strict相当于是指定了以下所有选项(未来还可能包括更多选项):

  • --strictNullChecks
  • --noImplicitAny
  • --noImplicitThis
  • --alwaysStrict

未来的 TypeScript 版本可能会在这个集合中添加额外的类型检查选项。这意味着咱们不需要监控每个 TypeScript 版本来获得应该在项目中启用的新严格性选项。如果向上述选项集添加了新选项,则在升级项目的 TypeScript 版本后,它们将自动激活。

--strict编译选项会为以上列出的编译器选项设置默认值。这意味着还可以单独控制这些选项。比如:

--strict --noImplicitThis false

或者在tsconfig.json文件指定:

{
  "strict": true,
  "alwaysStrict": false
}

这将是开启除--noImplicitThis编译选项以外的所有严格检查选项。使用这个方式可以表述除某些明确列出的项以外的所有严格检查项。换句话说,现在可以在默认最高级别的类型安全下排除部分检查。

改进的--init输出

除了默认的--strict设置外,tsc --init还改进了输出。tsc --init默认生成的tsconfig.json文件现在包含了一些带描述的被注释掉的常用编译器选项. 你可以去掉相关选项的注释来获得期望的结果。我们希望新的输出能简化新项目的配置并且随着项目成长保持配置文件的可读性。

通过tsc --init编译器可以为构建一个配置文件:

$ tsc --init

message TS6071: Successfully created a tsconfig.json file.

运行此命令后,会当前工作目录中生成一个tsconfig.json文件,生成的配置如下所示:

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
    // "lib": [],                             /* Specify library files to be included in the compilation:  */
    // "allowJs": true,                       /* Allow JavaScript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true                            /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */

    /* Source Map Options */
    // "sourceRoot": "./",                    /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "./",                       /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
  }
}

注意--strict是默认启用的。这意味着在启动一个新的TypeScript项目时,自动进入默认模式。

--checkJS选项下.js文件中的错误

即便使用了--allowJs,TypeScript 编译器默认不会报.js文件中的任何错误。TypeScript 2.3 中使用--checkJs选项,.js文件中的类型检查错误也可以被报出.

你可以通过为它们添加// @ts-nocheck注释来跳过对某些文件的检查,反过来你也可以选择通过添加// @ts-check注释只检查一些.js文件而不需要设置--checkJs编译选项。你也可以通过添加// @ts-ignore到特定行的一行前来忽略这一行的错误.

.js文件仍然会被检查确保只有标准的 ECMAScript 特性,类型标注仅在.ts文件中被允许,在.js中会被标记为错误。JSDoc注释可以用来为你的 JS 代码添加某些类型信息,

以上就是TypeScript泛型参数默认类型和新的strict编译选项的详细内容,更多关于TypeScript的资料请关注Devmax其它相关文章!

TypeScript泛型参数默认类型和新的strict编译选项的更多相关文章

  1. ios – 如何在Swift中使用没有类型参数的泛型类?

    解决方法Swift还不像Java那样支持wildcard-stylegenerics(即Animal

  2. ios – 如何在Swift中向下转换/转换结构的泛型类型

    我是否必须将这些存储为Any的数组,然后每次都将它们转换为或者我只是误解某些(或两者)?

  3. ios – 在XCTestCase子类中使用泛型有效吗?

    我有一个XCTestCase子类,看起来像这样.为了简洁起见,我已经删除了setup()和tearDown方法:它的子类看起来像这样:在理论上,这应该按预期工作–编译器不会抱怨任何事情.但是只是当我运行测试用例时,setup()方法甚至没有被调用.但是,它表明当testName()方法应该失败时,测试已经过去了.使用泛型是一个问题吗?我可以很容易地想到很多非通用的方法,但是我很想写这样的测试用例.这是XCTest在Objective-C和Swift之间的互操作性?Ergo您的通用XCTestCase子类不

  4. 泛型 – Xcode构建错误时,我添加枚举到泛型类?

    为什么在将泛型类添加到枚举时会收到错误:错误:但是当我这样做时,我没有收到错误:或这个:解决方法您不能将任何类型嵌套在通用的类型中,反之亦然.换句话说,你不能像类,结构和枚举这样做的事情:和乃至苹果人explained的限制原因:It’sanimplementationlimitation.We’llremovetherestrictiononceourcompilerandruntimearea

  5. ios – 如何通过Swift中的泛型类型构造一个属性?

    我在swift中创建了一个泛型类,我想使用“AdaptorType”类型初始化一个适配器,但是我收到一个编译错误我也尝试在init()中初始化它,但是同样的问题在于使用通用类型AdaptorType初始化适配器属性的正确方法是什么?

  6. ios – Equatable实现似乎不适用于泛型

    我仍然在与Swift仿制药作斗争.今天我发现我的Equatable协议实现不起作用,如果它是从泛型类调用的.我的模特课:类,使用泛型类型:它的子类:当我调用TrackingCache实例的removeEntities方法时,我总是在输出中得到相等的:false,即使id是相同的.但是,如果我直接将方法移动到TrackingCache类,它似乎工作正常!

  7. 泛型 – MonoTouch和支持变体通用接口

    如果是这样,MonoTouch中针对这种情况的推荐解决方法是什么?解决方法这实际上取决于编译器而不是Mono版本.IOW有些东西可能适用于Mono2.10而不适用于MonoTouch6.x.当前版本的MonoTouch附带了smcs编译器和基于2.1的配置文件.较新的功能,如协方差,需要一个完整的4.0编译器和运行时.未来版本的MonoTouch将提供4.0/4.5运行时和编译器.

  8. 寒城攻略:Listo 教你 25 天学会 Swift 语言 - 24 Generics

    它可以避免重复的代码,用一种清晰和抽象的方式来表达代码的意图//泛型是Swift强大特征中的一个,许多Swift标准库都是通过泛型代码构建出来的。{forinenumerate{//遍历索引固定字符串的下标ifvalue==valuetoFind{returnindex}}returnnil}letstrings=["cat","dog","llama","parakeet"]ifletfoundindex=findStringIndex{p

  9. Swift语法基础:7 - Swift的Generics

    在前面,我们知道了Swift中的Protocol和Extensions,现在我们来看看另一个东西:Generics(泛型)1.泛型的声明以及简单使用PS:所谓的泛型其实就是一个比较特殊的数组,它可以存储不同类型的数据,这样子我们在写方法的时候,就不需要再写多一个相同功能而类型不同的方法了.2.枚举类型中的泛型3.特定需求的泛型PS:如果你需要某个指定样式的泛型,那么就必须得在泛型里加上where这

  10. Swift泛型和泛型函数

    1、泛型函数在函数名后面加,参数类型也被声明为T,T成为占位符,函数在每次调用时传入实际的参数类型才决定T的类型funclog4{println}log4log4log4如果有多个不同类型,可以使用其它大写字母,一般习惯使用U,多个占位符使用逗号,隔开:示例如下:funcisEquals->Bool{}占位符不仅可以替代参数类型,还可以替代返回值类型:funcisEquals->T{}2、泛型约束有些占位符必须遵守某种协议,及T占位符后面添加冒号和协议类型,这种表示方式成为泛型约束,它能够替换T的类型。

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部