Extending a string in TypeScript

Gol*_*den 1 javascript typescript

When using generics in TypeScript, you sometimes see a type Parameter such as:

T extends string
Run Code Online (Sandbox Code Playgroud)

Isn’t this the same as using string directly? Can you subclass string? What would this be good for?

cyb*_*xae 7

下面是一个简单的示例,说明如何扩展字符串以及对类型进行硬编码会破坏它。

type Foo = string & Partial<{ meta: string }>

const foo: Foo = 'foo';
foo.meta = 'this string is important';

function hardCoded(x: string): string {
  return x;
}

hardCoded(foo).meta;  // this is an error

function generic<X extends string>(x: X): X {
  return x;
}
generic(foo).meta;  // but this works
Run Code Online (Sandbox Code Playgroud)

  • 实际上,似乎至少有一些 JavaScript 实现拒绝在字符串上存储属性。因此,虽然这在类型级别上有效,但在运行时可能不起作用。 (2认同)

bel*_*a53 5

type narrowedString =  "foo" | "bar"

// type ExtendsString = true
type ExtendsString = "foo" extends string ? true : false 

Run Code Online (Sandbox Code Playgroud)

"foo" and "bar" extend both the string type. For example that is useful, when you want to define enum like data structures (without the built in TypeScript enum type) or constants.

When a function offers a generic type parameter which extends string like T extends string, you can use that to enforce strong typing for your enums/constants.

function doSomething<T extends string>(t: T): {a: T} {
...
}

// invoke it
doSomething("foo" as const) // return {a: "foo"}

Run Code Online (Sandbox Code Playgroud)

Don't make the mistake to lump extends in TypeScript's typesystem together with extends from ES classes - they are two complete distinct operators.

extends对应instanceof于运行时并作为构造存在于运行时,而在类型系统中(extends例如,与条件类型一起发生),可以转换为“可分配给”,并且仅用于编译时。

更新:

您可以在TypeScript文档中找到有关字符串文字类型的更多信息。

  • &lt;&lt;“ foo”和“ bar”都扩展了字符串类型&gt;&gt;我认为,更窄的String扩展字符串类型会更正确(特别是通过禁止除“ foo”或“ bar”之外的其他值) (2认同)