1. 程式人生 > 其它 >TypeScript 型別學習4

TypeScript 型別學習4

interface Shape {
  kind: "circle" | "square"; //為了避免錯誤,規定的字面量型別
  radius?: number;
  sideLength?: number;
}
function handleShape(shape: Shape) {
  if (shape.kind === "circle" && shape.radius)
    return Math.PI * shape.radius ** 2; //但是!不推薦使用
}

interface Circle {
  kind: "circle";
  radius: number;
}
interface Square {
  kind: "square";
  sideLength: number;
}
interface Sun {
  kind: "sun";
  sideLength: number;
}
/**
 *  可辨識聯合
 */
type AreaShape = Circle | Square | Sun;
function getArea(shape: AreaShape) {
  switch (shape.kind) {
    case "square":
      return shape.sideLength ** 2;
    case "circle":
      return Math.PI * shape.radius ** 2;
  }
}

/**
 * never型別和完整性檢查 永不存在的值的型別
 * 在 switch 當中判斷 type,TS 是可以收窄型別的;
 * 但是如果加入新的同事,新的同事給你加了新的型別,但是他忘了給你對應的邏輯。
 * 當沒有涵蓋所有可辨識聯合的變化時,我們想讓編譯器可以通知我們。
 * never就起了作用併產生一個編譯錯誤。所以通過這個辦法,你可以確保 getKind 總是窮盡了所有 AreaShape 的可能型別。
 */
function getKind(shape: AreaShape) {
  switch (shape.kind) {
    case "square":
      return shape.sideLength ** 2;
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "sun":
      return Math.PI * shape.sideLength ** 2;
    default:
      const _check: never = shape;
      return _check;
  }
}
/**
 * 函式型別表示式
 * fn:(a:string)=>void
 */
type GreeterFunction = (a: string) => void;
function greeter(fn: GreeterFunction) {
  fn("函式型別表示式");
}
function printToConsole(s: string) {
  console.log(s);
}
greeter(printToConsole);

/**
 * 呼叫簽名
 */
// type DescribeFunction = {
//   describction: string;
//   (someArg: number): boolean;
// };
// function handleSomthing(fn: DescribeFunction) {
//   console.log(fn.describction + "return" + fn(999));
// }
// function call(n: number) {
//   console.log(n);
//   return true;
// }
// call.describction = "hello";
// handleSomthing(call);

/**
 * 泛型函式 可以使用泛型來建立可重用的元件
 * @param arg
 * @returns 使用any型別會導致這個函式可以接收任何型別的arg引數,
 * 這樣就丟失了一些資訊:傳入的型別與返回的型別應該是相同的。
 * T是型別變數
 * 使用後可以讓我們去跟蹤使用的型別的資訊
 * 怎麼使用型別變數
 */
function TypeAcceptAny(arg: any) {
  return arg;
}
let ssss = TypeAcceptAny("232");

function TypeAccept<B>(arg: B) {
  return arg;
}
function TypeArray<Type>(arr: Type[]) {
  return arr[0];
}
/**
 * 第一種型別明確寫法
 * 第二種型別推論寫法 更普遍
 * 但是如果編輯器不能自動推斷出型別的話,就應該明確的傳入型別
 * 需要注意的點
 * 建立泛型函式時,編譯器要求你在函式體必須正確的使用這個通用的型別。
 */
let color = TypeAccept<string>("#fff");
let age = TypeAccept(18);

let number = TypeArray([1, 2]);
let string = TypeArray(["1"]);

/**
 * 泛型不光可以定義一個 也可以定義多個
 */
function MapItem<Input, Output>(
  arr: Input[],
  fun: (arg: Input) => Output
): Output[] {
  return arr.map(fun);
}
const parse = MapItem(["1", "2", "3"], (n) => parseInt(n));