vi进入编辑后不能打字_打字稿进入未知

这篇内容提及了一个常见的问题——在使用vi编辑器时遇到无法打字的困扰。通常,这可能是因为进入了错误的模式。解决方案通常涉及到切换到插入模式以便开始输入。
摘要由CSDN通过智能技术生成

vi进入编辑后不能打字

TypeScript code around the world is littered with the any type, and it drives me absolutely crazy. There is no (valid) reason to use it in application code, and you are opting out of the safety of a static type system.

世界各地的打字稿代码充斥着的any类型,它驱使我绝对是疯了。 没有(有效的)理由在应用程序代码中使用它,并且您选择退出静态类型系统的安全性。

Many developers who are new (or not so new to TypeScript) assume that when you don’t know what type you are going to get, you should type it with any. TypeScript’s official documentation also tells you that this is not the case:

许多新手(或者对TypeScript不太陌生)的开发人员都假定,当您不知道要获得哪种类型时,应该使用any键入。 TypeScript的官方文档还告诉您事实并非如此:

“Don’t use any as a type unless you are in the process of migrating a JavaScript project to TypeScript. The compiler effectively treats any as “please turn off type checking for this thing”. It is similar to putting an @ts-ignore comment around every usage of the variable. This can be very helpful when you are first migrating a JavaScript project to TypeScript as you can set the type for stuff you haven’t migrated yet as any, but in a full TypeScript project you are disabling type checking for any parts of your program that use it.”

“除非正在将JavaScript项目迁移到TypeScript的过程中,否则请勿将any类型用作类型。 编译器有效地将any视为“请关闭此类型的类型检查”。 这类似于在变量的每种用法周围使用@ts-ignore注释。 当您第一次将JavaScript项目迁移到TypeScript时,这可以非常有用,因为您可以将尚未迁移的内容的类型设置为any ,但是在完整的TypeScript项目中,您将禁止对程序的任何部分进行类型检查。用它。”

Unless you are adding type definitions to an open source JavaScript library, do not use any. If you are maintaining an open source JS library, then I appreciate you adding type definitions at all and understand the time constraints you are under. If throwing in an any here and there allows you to add types to 90% of your API, then I think this is a valid use case. I hope they are all refactored to unknown one day when time permits. Ideally, members of the TypeScript community could make PRs and help refactor these for you.

除非您将类型定义添加到开源JavaScript库中,否则请不要使用any 。 如果您要维护一个开源JS库,那么我非常感谢您添加类型定义,并了解您所处的时间限制。 如果在此处乱扔any东西,使您可以将类型添加到90%的API中,那么我认为这是一个有效的用例。 我希望在时间允许的情况下将它们全部重构为unknown一天。 理想情况下,TypeScript社区的成员可以制作PR并帮助您重构它们。

What if I want to accept anything or don’t know the type I’ll get? Again, TypeScript’s documentation comes to the rescue:

如果我想接受任何东西或不知道会得到的类型怎么办? 同样, TypeScript的文档可以帮助您:

“In cases where you don’t know what type you want to accept, or when you want to accept anything because you will be blindly passing it through without interacting with it, you can use unknown.”

“在您不知道要接受哪种类型的情况下,或者由于不与之交互而盲目地将其传递而不想接受任何内容时,可以使用unknown 。”

未知类型 (The unknown Type)

In TypeScript 3.0, we got the unknown type, which let us signal “This can be any value, so you must perform some type checking before you use it.” Unlike with any, you cannot access any properties on values with the type unknown or call/construct them. unknown forces us to safely introspect return values.

在TypeScript 3.0中,我们得到了unknown类型,该类型使我们发出信号“这可以是任何值,因此在使用它之前必须执行一些类型检查。” 与any不同,您不能访问类型为unknown值的任何属性或调用/构造它们。 unknown迫使我们安全地检查返回值。

一个简单的例子 (A simple example)

You can see an example of how any just completely ignores the type checker:

你可以看到怎样一个例子any只是完全忽略类型检查:

type anyType = { prop1: any, prop2: any }


const anyFoo: anyType = {
  prop1: 'hello',
  prop2: { foo: 'bar'}
}


// No Errors - This defeats the purpose of TypeScript
console.log(anyFoo.prop2.whatever)

Conversely, if we type this as unknown, we do get an error — albeit one that confuses a lot of people:

相反,如果我们将其键入为unknown ,则确实会得到一个错误,尽管这会使很多人感到困惑:

type unknownType = { prop1: unknown, prop2: unknown }
const unknownFoo: unknownType = {
  prop1: 'hello',
  prop2: { foo: 'bar'}
}


// Error: Object is of type 'unknown' 🤷‍♂️
console.log(unknownFoo.prop2.foo)

对象的类型未知(Object is of type unknown)

This error confuses a lot of people. Unlike many of the helpful TypeScript messages, this one doesn’t really explain what the issue is (unless you understand the unknown type). Earlier, I mentioned one of the subtler characteristics of unknown that can be easy to miss when browsing docs: You cannot access any properties on values with the type unknown.

此错误使很多人感到困惑。 与许多有用的TypeScript消息不同,该消息并没有真正解释问题的根源(除非您了解unknown类型)。 之前,我提到过unknown的微妙特征之一,在浏览文档时很容易错过:您无法访问unknown类型的值的任何属性。

TypeScript makes us narrow the scope of a broad type (unknown) down to a narrower type. Generally, you’d want to do something like below:

TypeScript使我们将宽泛类型( unknown )的范围缩小到较窄类型。 通常,您需要执行以下操作:

if (
  unknownFoo.prop2 // check it is not null
  && typeof unknownFoo.prop2 === 'object' // check its an object
  && Object.hasOwnProperty.call(unknownFoo.prop2, 'foo')
) {
  console.log(unknownFoo.prop2.foo);
}

Unfortunately, while this code is perfectly safe, TypeScript isn’t (currently) able to extend the type of unknownFoo.prop2 with foo even though it is a valid guard clause to check if the property exists.

不幸的是,尽管此代码是绝对安全的,但TypeScript无法(当前)使用foo扩展unknownFoo.prop2的类型,即使它是检查属性是否存在的有效保护子句也是如此。

Lots of people get stuck here and give up. Personally, I was happy to sink many hours into solving this. What’s the point of this new type if we can’t use it for the majority of cases in which we’d actually want to use it? We need to create a little helper function to get the correct typings. The following gist shows the code we need:

很多人陷在这里放弃了。 就个人而言,我很高兴花很多时间来解决这个问题。 如果我们不能在大多数实际需要使用的情况下使用这种新类型,那又有什么意义呢? 我们需要创建一个小的辅助函数来获取正确的类型。 以下要点显示了我们需要的代码:

function hasOwnProperty<X extends {}, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, unknown> {
  return Object.hasOwnProperty.call(obj, prop)
}

If we use the helper above, we get full type safety:

如果我们使用上面的帮助器,我们将获得全类型的安全性:

type unknownType = { prop1: unknown; prop2: unknown }
const unknownFoo: unknownType = {
  prop1: 'hello',
  prop2: { foo: 'bar' },
};


function hasOwnProperty<X extends {}, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, unknown> {
  return Object.hasOwnProperty.call(obj, prop);
}


if (
  unknownFoo.prop2
  && typeof unknownFoo.prop2 === 'object'
  && hasOwnProperty(unknownFoo.prop2, 'foo')
) {
  // No TS errors!!
  console.log(unknownFoo.prop2.foo);
}S

Wait… what? How?

等等...什么? 怎么样?

Our little utility function harnessed the power of Generics and Type Predicates in TypeScript.

我们的小工具功能利用TypeScript中泛型类型谓词的功能。

The Generics are this part: <X extends {}, Y extends PropertyKey>. We want to make sure that the first argument extends the object type {} and the second argument extends the PropertyKey type. PropertyKey is a built-in alias for the Union type of string, number, and symbol. Basically, valid key types in a JS map: type PropertyKey = string | number | symbol.

泛型就是这一部分: <X extends {}, Y extends PropertyKey> 。 我们要确保第一个参数扩展对象类型{} ,第二个参数扩展PropertyKey类型。 PropertyKey是一个内置的别名Union类型的字符串,数字和符号组成。 基本上,JS映射中的有效键类型为: type PropertyKey = string | number | symbol type PropertyKey = string | number | symbol type PropertyKey = string | number | symbol

Type Predicates are very powerful in TypeScript for narrowing down types conditionally. The basic idea is that if the function predicate returns true, retype the parameter to a new type.

类型谓词在TypeScript中非常强大,可以有条件地缩小类型。 基本思想是,如果函数谓词返回true ,则将参数重新键入为新类型。

In our example, the predicate is Object.hasOwnProperty.call(obj, prop). Predicate is just a fancy name for a boolean conditional. Basically, if our object has this property, we return true, which tells the Type Predicate to retype our value.

在我们的示例中,谓词为Object.hasOwnProperty.call(obj, prop) 。 谓词只是布尔条件的奇特名称。 基本上,如果我们的对象具有此属性,则返回true ,它告诉Type Predicate重新输入我们的值。

The last piece of the puzzle here is obj is X & Record<Y, unknown>. This is the part that retypes our parameter if the predicate returns true. It says obj (our first param is hasOwnProperty) is (forcing a type recast) X & Record<Y, unknown> (our new type).

最后一个难题是obj is X & Record<Y, unknown> 。 如果谓词返回true则这是重新输入参数的部分。 它说obj (我们的第一个参数是hasOwnProperty )(强制重铸类型) X & Record<Y, unknown> (我们的新类型)。

X & Record<Y, unknown> is just an intersection type. It says its Xis merged in with a Record of key Y and value unknown. A Record type is a utility type in TypeScript.

X & Record<Y, unknown>只是一个交集类型。 它说它的X与键Y记录unknown值合并。 记录类型是TypeScript中的实用程序类型。

在野外未知 (Unknown in the Wild)

unknown generally occurs in the wild at your API boundaries. I can’t really think of a case where you won’t know the data type internally. For this reason, I don’t really like a lot of the basic examples you see, such as this one:

一般情况下,您的API边界通常会发生unknown事件。 我真的想不出内部不知道数据类型的情况。 因此,我不太喜欢您看到的许多基本示例,例如:

const val1: unknown = 'Hello, World!';
// TS Error: Object is of type 'unknown'
val1.toUpperCase();


const val2: unknown = 'Hello, World!';


if (typeof val1 === 'string') {
  // This works as we've narrowed the type to a string
  val2.toUpperCase();
}

While I think the example above is a great way to highlight how we need to narrow down the type in order to access properties on an unknown type, it’s really hard to picture where you’d ever see this in real life.

虽然我认为上面的示例是突出显示我们如何缩小类型以便访问unknown类型的属性的好方法,但实际上很难想象您在现实生活中会看到什么。

The majority of the cases where I use an unknown is at an API boundary, and it’s usually in a Record utility type and looks something like this:

我使用unknown的大多数情况是在API边界,并且通常在Record实用程序类型中,看起来像这样:

const parameterBag: Record<PropertyKey, unknown> = {
param1: 1,
param2: { foo: 'bar ' },
param3: 'Hello, World!',
};

结语 (Wrapping Up)

One of the biggest complaints about adding the unknown type is that it makes code verbose and tricky to write. My only response to that is “That’s the point!” The whole point of it is to force you to handle every possible case for an unknown type. This is naturally going to be a verbose process. If your data type isn’t truly unknown, then don’t type it that way.

有关添加unknown类型的最大抱怨之一是,它使代码变得冗长且难以编写。 我对此的唯一回答是“这就是重点!” 这样做的全部目的是迫使您处理unknown情况下的所有可能情况 类型。 这自然将是一个冗长的过程。 如果您的数据类型不是真正unknown ,则不要那样键入。

To guard yourself from the dangers of any, I suggest using an eslint rule to error on usage of explicit any as well as changing your tsconfig to error on implicit any types.

为了保护自己免受any的危害,我建议使用eslint规则在显式any使用上出错,以及将tsconfig更改为隐式的any类型的错误。

//eslintrc.json
"@typescript-eslint/no-explicit-any": ["error", {}],// tsconfig.json
"noImplicitAny": true,

翻译自: https://medium.com/better-programming/typescript-into-the-unknown-4c19d913cb15

vi进入编辑后不能打字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值