Closed56

satisfiesメモ

makototmakotot
makototmakotot

another way to assign types to values.

値に型を割り当てる方法

makototmakotot

まず型割り当ての復習。

値の型をコロンに続けて明示的にアノテーション

const obj: Record<string, string> = {};

obj.id = "123";

値がアノテーションの型そのものであり、その型のみを許容。

makototmakotot
let id: string | number = "123";

if (typeof numericId !== "undefined") {
  id = numericId;
}

型をユニオンでwidenしてアノテーションもできる。

makototmakotot

エッジケースの欠点がある。

When you use a colon, the type BEATS the value.

コロンによる型アノテーションによって、値を型が打ち負かす。

makototmakotot

In other words, if you declare a wider type than you want, you're stuck with the wider type.

広めに型定義したら広めな型に留まる

const routes: Record<string, {}> = {
  "/": {},
  "/users": {},
  "/admin/users": {},
};

// No error!
routes.awdkjanwdkjn;
makototmakotot

This means it infers the narrowest possible type, not the wider type you specify

可能な限り最も狭い型を推論する

makototmakotot

asによる型定義は嘘になり得る

type User = {
  id: string;
  name: {
    first: string;
    last: string;
  };
};

const user = {} as User;

// No error! But this will break at runtime
user.name.first;

There are some limits to the lies– you can add properties to objects, but you can’t convert between basic types.

ただし基本型の間での嘘はつくことができない。
asを繰り返したりしない限りは。

const str2 = "my-string" as unknown as number;
makototmakotot

There’s one last way to give a type to a variable:

Don’t.

型付けするもう1つの方法は型定義しないこと。推論を効かせる。

makototmakotot
  • colon annotations
  • satisfies
  • as annotations
  • not annotating and letting TS infer it

まとめると値に型を指定する方法は、コロンに続けて型指定、satisfiesas、型を書かずに推論を効かせる、の4通り

makototmakotot

But most of the time, when you want to assign a type to a variable you probably want the type to be wider.

変数に型割り当てるなら、大抵広めに型付けしておきたいかもしれない

makototmakotot

The rule of thumb is that you should only use satisfies in two specific situations:

  • You want the EXACT type of the variable, not the WIDER type.
  • The type is complex enough that you want to make sure you didn’t mess it up

経験則から考えるsatisfiesが必要なケースは2つだけ

  • 正確な型が必要なとき
  • 何か誤っていないか確認したいほど複雑な型
makototmakotot
makototmakotot

The new satisfies operator lets us validate that the type of an expression matches some type, without changing the resulting type of that expression.

式の結果の型を変更することなく、式の型を検証できるもの。

makototmakotot

Maybe we don’t care about if the property names match up somehow, but we do care about the types of each property. In that case, we can also ensure that all of an object’s property values conform to some type.

オブジェクトのプロパティ毎に型を検証できる。

makototmakotot
makototmakotot

as const type assertions can also be used to modify types. But those add readonly to all array and object types, which also might not be what you want

as constはすべてのobjectとarrayをreadonlyに。

makototmakotot

TypeScript's default type inference for objects defaults to inferring primitive values for types, rather than literals.

デフォルトのオブジェクトに対する型推論だと、リテラル型ではなくプリミティブ型

makototmakotot

明示的に型アノテーションでも、ユニオンが型狭められてないことで開発者には直観的とはいえない

makototmakotot

TypeScript 4.9's new satisfies operator introduces a happy compromise between : annotations and the default type inference.

satisfiesは型推論と明示的な型アノテーションの間を埋めるものになる?

makototmakotot

In other words, satisfies makes sure a value's type matches some type shape, but doesn't widen the type unnecessarily.

satisfiesはある型の形状にマッチすることを検証できて、不要なwidenをしない。

makototmakotot

型アノテーションだとユニオンになるものが、satisfiesだとリテラル型になる

interface Vibe {
  mood: "happy" | "sad";
}
 
const vibe = {
  mood: "happy",
} satisfies Vibe;
 
vibe.mood;
// 型が"happy"になる
makototmakotot
makototmakotot

it ensures that a type has all the required properties and methods of a specific interface.

特定のインターフェースに必須のプロパティとメソッドを全て持っていることを検証できる。

makototmakotot

Having to always validate whether it is a string can be frustrating and cumbersome. This is where the satisfies operator comes in.

従来のtsだとunion型で都度値をチェックする処理が必要で面倒だったけど、satisfiesだとそれが解消される

makototmakotot

We can also use the satisfies operator to tell the TypeScript compiler that it’s OK for an object to include only a subset of the given keys but not accept others.

オブジェクトのキーに制約をかけることができる

makototmakotot

Similar to property name constraining, with the exception that in addition to restricting objects to only contain specific properties, we can also ensure that we get all of the keys using the satisfies operator.

オブジェクトの全てのキーが欠落していないかのチェックもできる

makototmakotot

The satisfies operator is not only capable of restricting the names of properties in an object, but it can also restrict the values of those properties.

オブジェクトのキーだけではなく値にも制限をかけられる。

makototmakotot
makototmakotot

When using colon annotation, the type supercedes the value. This means that if you declare a wider type (such as Record) and then try to assign and access a narrower value, typescript will not help you.

コロンアノテーションで広めに型定義したら、狭めに値を扱いたいケースでtsの助けはない。

makototmakotot

The satisfies keyword is a way to say "this value satisfies this type".

satisfiesは、ある値がある型を満たしているという型定義。

makototmakotot

This is useful when you want to ensure a value is of the correct type, while keeping it as narrow as possible.

型をなるべく狭めつつ、その型に当てはまる値であることを確かなものとしたいときに便利。

makototmakotot
makototmakotot

Safe Upcast

The safest workaround is to have a dummy function, function up<T>(arg: T): T

安全に型をアップキャストするならダミー関数作ることに。

makototmakotot

Property Name Constraining

We might want to make a lookup table where the property keys must come from some predefined subset, but not lose type information about what each property's value was:

オブジェクトのプロパティ名に制約をかけつつ各プロパティの型情報を保つ方法がない?

makototmakotot

Property Name Fulfillment

Same as Property Name Constraining, except we might want to ensure that we get all of the keys:

すべてのプロパティが欠けてないことを保証する方法がない?

makototmakotot

Property Value Conformance

This is the flipside of Property Name Constraining - we might want to make sure that all property values in an object conform to some type, but still keep record of which keys are present:

オブジェクトの各プロパティ値がある型に一致することを確かめたい?

makototmakotot

Ensure Interface Implementation

We might want to leverage type inference, but still check that something conforms to an interface and use that interface to provide contextual typing

型推論を活かしつつ、インターフェイスを満たすかチェックしたい?

makototmakotot

Optional Member Addition

オプショナルメンバーの追加に柔軟性が足りずエラー扱いになる?

makototmakotot

このissueで取り上げられているユースケースについてのplayground
https://www.staging-typescript.org/play?ts=4.7.0-pr-46827-30#code/C4TwDgpgBA0hIGcoF4oHICGaoB90CNs80BjI9AEzQG4AoWgegagGEALCEgaymDY2BQMAG2FQwAJwD2kCaChd4SElIB2AMykSAtrylQEU7dFCRaK1QkGHjABWlgEAeXVxEKKAG9aUX0IBcUAAMADQ+fviBAEQcolJRYX5QAB6BABxQTFAAoskkEAhIkjIQciBQAJZI6sIYAOZ1EBS0AL4GAlXqFQVQthhyFSIAPABKnFoUQ24IIVAArqpcqlIA7qoAfOt0jMwAKuDQFRpa2h1qUFLqUBAYJGziDqXyVVCnR8AYR020NhD2Ms5XEoAHQYYHAKQAMQqySaAAoAJR0X7-RwuabA-DAhBzfBWCRHOpwgCMSJ2UAAysAKqIhKprhJpBJZmgqJUkNoqghCeY1IZhBBgcIpESUQ5ARiKGTyexODw+AIhLTirJ5Ip3P1oJIChBVMBeZZBCJhKiJUoPN4khhAqFwr5IlAYhA4gk7VASIFgBI5hBWu1qQguj0xioJJNprMFktVhtqJlmBR2a8uTysvtIJVjjozvSJBAPl9mgKjR5jab0SCwRDobCKIi6MWoPhS6Jy0DEJjsbj8STpVlZdxePwjcrHgMegA3EQ+91qTQ6PQGIwmA60UzQSG3YBIVCeKAAbXVgXxhIAuoF8FIpAKMPSWnQKJxanmoOoFiRqec7nLdt6+Ag4VSKBNw-BAEUCCcpAqCgHyfTVX3fT96W-bgAEkEAAQRWDBFEAwI9yqLCcIgC8rxvO9wKgSDoLoCwrBSC03UI7DFE9b1fTaBAOkDbokBA7c6CyAAhKQ+CgJwYHMDhuF-OZ-0AskUK4dCiNw5IySybJGS0WYjkfZIDAqOpVAEOYXwoKQClUNBBBIPMBGgfp8AqL1+nKFUnl4g1+UFYUiWSYEAC8NOYABZKpTmAb9Ew8soqOnQ5qlqBpvjowRkgAJkYpJtDYn1Ej8BBonUEQEAgKI-S4gMgz4rcEG2LIMOWPhSmuZIMG0MABVoCBkjALRBHXVhry0C0oAkQJVDmbR8FKWY6km6bZuZJtFpm1r73JDDaUuIcdQMNgpDmYRE1m4bhQkGYmzkqBUIuVRhHKOYyqXYwLiuFrdA4PNgR6vqBtnQ1ehEfNgGgXc3RWNgXJIrxxsCDKAFZEfmhHkdmB0kcRqAWgK+1am4fD4eCVGSagCgbRx2YsiGABaC4AQAQkobAjnEAnoF2tBCDdfBhB9ImJrJhaycx5Gqcq7iaqgEMJiGE9VDqWYWBGiQtm869fJFOE+mLMHMX5iAQuGxlOGAR7X2SxpEwwJBSiZDWBSFbXddB3yjLYYAAH0zK6o3tnJVC9VKEr8kqTqBWMPUczXA4oFCqQpz58GvDdbRE4gOEKCqD5VHyNblso6iYNaWi+Vs-pssKj45EROHcbTjOs4RVOkiSLJEwQQ7jtO6ApvWiQ3QbpIrBkOu9xaSXqt4+PE4wZOoAAMhl8Yw3lr1CUjRZljWdWsjbg+D4APRP0+z-Pi+z-JQ+b98KJtuFFY2vyQoHhKccEAqmVpJ4GQkJEN+qpyjriQFDGkWo8xlQkBOQkDwdR50OMcWOGZbBQT1BlRMu4UgFzmlAEAOCJA4zLkDbQIBUHvDGkBYkQQcb+k6DPPoAxhjkPQRQdWaVXhkLQcAISGBMFwyAlEahURaFVXoT0Rh1JmHcIwXvZgElZjLCgMzVQEAmhNCgN9X0dFNbOyJKQlhwBgQBWrDCeECJjYUm7idBkDtGxgA8AY7hwIQANWYCrYOyRgBzAAaYHkQ17BNAqCQByO44b7iKgYDeitzxQDhKoAhLdkDrCbGRG4d5tgcO1BQSJgTs4hLBmEy0fgqjZAnLqSaKAUn0gAKRQCysgRpJMmLOAoBTKA9JkkdKgHUhpTTiRT3EUgPJwTQl0CAA

このスクラップは2023/05/12にクローズされました